【问题标题】:Tkinter Treeview not showing newly inserted items, no errors givenTkinter Treeview 没有显示新插入的项目,没有给出错误
【发布时间】:2019-04-13 19:01:28
【问题描述】:

我正在构建一个桌面应用程序,可让您将一些数据插入表单,然后将数据显示在一系列 (3) 的 Treeview 小部件中。 这是我用来输入新数据的表格:

它位于顶级小部件中。当按下 Add 按钮时,新数据存储在一个文件中,它还应该将新数据插入相应的 Treeview Widget。 这是根窗口:

它由 3 个 Treeview 小部件组成。该应用程序的目的是让用户有机会将候选人分类到正确的 Treeview 小部件中。 我面临的问题是,当按下添加按钮时,新数据不会显示在 Treeview 小部件中,并且没有给出错误。我认为这可能是类实例化的问题。 这是我的应用程序的摘录,请参阅下面的最小、完整且可验证的示例

class MainApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        ...
        # frame and menu classes are instantiated here
        self.FrameList = {ViableCandidates: ViableCandidates(self),
                          NotViableCandidates: NotViableCandidates(self),
                          InProgressCandidates: InProgressCandidates(self)}
        ...
    def InstanceLinker(self, frame):
        link = self.FrameList[frame]
        return link
class GUIMenu(tk.Menu):
    def __init__(self, parent):
        ...
    # menu code is here
    addcandidates.add_command(label='Quick Add', command=lambda: QuickAdd(parent))
class QuickAdd(tk.Toplevel):
    def __init__(self, parent):
        ...
    # code for the small Toplevel window
    ...
    # this is the code that I use to add the new item to Treeview when the Add button is pressed
    if CandidateInfo['status'] == 'Viable':
        app.InstanceLinker(ViableCandidates).AddtoList()
    elif CandidateInfo['status'] == 'Not Viable':
        app.InstanceLinker(NotViableCandidates).AddtoList()
    else:
        app.InstanceLinker(InProgressCandidates).AddtoList()
# ViableCandidates, NotViableCandidates, InProgressCandidates are created with the same pattern
class InProgressCandidates(tk.Frame):
    def __init__(self, parent):
        global Counter
        tk.Frame.__init__(self, parent)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(1, weight=1)
        title = tk.Label(self, text="Candidates In Progress", font="Verdana 10 bold")
        title.grid(row=0, column=0, sticky='nesw')
        self.tree = ttk.Treeview(self)
        self.tree.grid(row=1, column=0, sticky='nesw')
        scrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
        scrollbar.grid(row=1, column=1, sticky='nws')
        self.tree.config(columns=('Name', 'Date'), selectmode='browse', height=20, yscrollcommand=scrollbar.set)
        self.tree.column('#0', width=20, minwidth=10, stretch=tk.YES)
        self.tree.column('Name', width=150, minwidth=10, stretch=tk.YES)
        self.tree.column('Date', width=80, minwidth=10, stretch=tk.YES)
        self.tree.heading('#0', text='#', anchor=tk.W)
        self.tree.heading('Name', text='Name', anchor=tk.W)
        self.tree.heading('Date', text='Date', anchor=tk.W)
        if Counter < 4:
            Counter += 1
            self.PopulateList()
    def PopulateList(self):
        selection = Database().SelectFromDB('name, date', "status = 'In progress'")
        for i in range(len(selection)):
            name = list(selection[i])[0]
            date = adjusttotimezone(list(selection[i])[1])
            self.tree.insert("", i, name, text=i + 1)
            self.tree.set(name, 'Name', name)
            self.tree.set(name, 'Date', date)
            CandidateCounter['InProgressCandidates'] = i
    def AddtoList(self):
        CandidateCounter['InProgressCandidates'] += 1
        print('I was here')
        self.tree.insert("", CandidateCounter['InProgressCandidates'], CandidateInfo['name'],
                         text=CandidateCounter['InProgressCandidates'])
        self.tree.set(CandidateInfo['name'], 'Name', CandidateInfo['name'])
        selection = Database().SelectFromDB('date', "name = '" + CandidateInfo['name'] + "'")
        date = adjusttotimezone(list(selection[0])[0])
        self.tree.set(CandidateInfo['name'], 'Date', date)
app = MainApp()
app.mainloop()

当按下“添加”按钮时,没有错误并且打印“我在这里”,因此实例化了 AddtoList 方法,但没有新项目添加到 Treeview。我确实检查了用于创建新 Treeview 项目的变量是否包含正确的数据,并且确实如此。

编辑:这是一个最小、完整且可验证的示例:

import tkinter as tk
from tkinter import ttk
Bigbadtext = ''
Counter = 0
class MainApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        self.MainWindow = tk.Tk.__init__(self, *args, **kwargs)
        menu = GUIMenu(self)
        self.config(menu=menu)
        frame = InProgressCandidates(self)
        frame.grid(row=0, column=1, sticky='nesw')
        self.FrameList = {InProgressCandidates:InProgressCandidates(self)}
    def InstanceLinker(self, frame):
        link = self.FrameList[frame]
        return link
class GUIMenu(tk.Menu):
    def __init__(self, parent):
        tk.Menu.__init__(self, parent)
        addcandidates = tk.Menu(self, tearoff=0)
        self.add_cascade(label='Add Candidates', menu=addcandidates)
        addcandidates.add_command(label='Quick Add', command=lambda: QuickAdd(parent))
class QuickAdd(tk.Toplevel):
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        saysomething = tk.Entry(self)
        saysomething.grid(row=1, column=0)
        def addbutton():
            global Bigbadtext
            Bigbadtext = saysomething.get()
            app.InstanceLinker(InProgressCandidates).AddtoList()
        okbutton = ttk.Button(self, text='Add', command=addbutton)
        okbutton.grid(row=2, column=0)
class InProgressCandidates(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.tree = ttk.Treeview(self)
        self.tree.grid(row=1, column=0, sticky='nesw')
        scrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
        scrollbar.grid(row=1, column=1, sticky='nws')
        self.tree.config(columns='something', selectmode='browse', height=20, yscrollcommand=scrollbar.set)
        self.tree.column('#0', width=20, minwidth=10, stretch=tk.YES)
        self.tree.column('something', width=150, minwidth=10, stretch=tk.YES)
        self.tree.heading('#0', text='#', anchor=tk.W)
        self.tree.heading('something', text='Say something', anchor=tk.W)
    def AddtoList(self):
        global Counter
        Counter += 1
        print('I was here')
        self.tree.insert("", Counter, Bigbadtext, text=Counter)
        self.tree.set(Bigbadtext, 'something', Bigbadtext)
app = MainApp()
app.mainloop()

【问题讨论】:

  • 验证您的Scrollbar 是否正常工作*
  • 它工作正常。当我添加新项目时它没有反应,但在我重新运行代码并重新填充列表后它工作正常。
  • 对不起,我刚刚看到我上传的树视图图片中的项目数接近滚动条处于活动状态。滚动条很好。按下“添加”按钮时没有将新项目添加到树视图的问题一直发生(即使树视图中有 1-2 个项目)
  • 贴出的代码至少有一个缩进问题。我们还需要您发布minimal reproducible example。即使缩进已修复,您发布的代码也不会运行。
  • 感谢您的回复,我将使我的代码最小化且可验证。我发布的代码是我认为与我的较大代码最相关的内容的摘录。

标签: python tkinter treeview


【解决方案1】:

问题是您正在创建 两个 树视图小部件,然后将项目添加到不可见的小部件。

你在这里创建一个:

frame = InProgressCandidates(self)

然后你在这里创建另一个:

self.FrameList = {InProgressCandidates:InProgressCandidates(self)}

既然您已经创建了一个,那么您创建的应该是self.FrameList 中的内容:

self.FrameList = {InProgressCandidates:frame}

【讨论】:

  • 非常感谢。有效。我是 Python 新手,现在我突然意识到,当使用类作为字典中的值时,它实际上会创建一个新实例。我认为它实际上会使用刚刚实例化的实例。非常感谢。
【解决方案2】:

这不是一个真正的答案,但我对这个问题投了赞成票,因为它解决了我的一个问题。我想向小部件添加项目,但在完成填充树之前不想将其显示给用户。但是每个插入都立即显示。现在我创建了 2 个相同的小部件,一个可见,另一个不可见,一旦填充,我在它们之间进行更改。因此,即使是错误也会有好处。

【讨论】:

  • 如果不是答案,请将其写为评论。
猜你喜欢
  • 2020-02-07
  • 2016-08-26
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
  • 2019-05-17
相关资源
最近更新 更多