【问题标题】:tkinter Treeview's insert method is not working when accessed from outside of the class从类外部访问时,tkinter Treeview 的插入方法不起作用
【发布时间】:2021-08-07 06:51:26
【问题描述】:

我正在尝试在 tkinter Treeview 中插入新条目,但它不起作用并且没有显示任何错误。 以下是我的代码的小版本。

class First:
   ...
   ...
    for c in self.bill_tree.get_children():
        i = self.bill_tree.item(c)['values']
        Second().add_to_tree(i)
   ...
   ...

我想做的是让First 班级的孩子,然后将他们插入Second 班级,但它不起作用。我创建了一个add 方法来测试并插入数据,但是当我尝试使用add_to_tree 时它失败了。

class Second:
     ....
     self.bill_tree1 = ttk.Treeview(self, show='tree')
     tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree1.yview)

     self.bill_tree1.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3''))
     self.bill_tree1.column("#0", stretch='no', minwidth=0, width=0)
     self.bill_tree1.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
     self.bill_tree1.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
     self.bill_tree1.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

     tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
     self.bill_tree1.place(relx=0.013,rely=0.185, width=780, height=301)

 def add(self):
     self.bill_tree1.insert('','end', values=('value 1','value 2','value 3'))

 def add_to_tree(self, i):
     self.bill_tree1.insert('','end', values=(i))

以下是我的项目的迷你示例,其中所有类都是从主类调用创建的,并相互叠加以实现多页窗口。

from tkinter import ttk, messagebox
import tkinter as tk

class Home(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)

        container.pack(fill='both', expand=True)

        l = [[1,2,3],[4,5,6]]

        Second().add_to_tree(l)
        
        self.frames = {}

        for F in (Second, First):
            frame = F(container, self)
            self.frames[F] = frame
            frame.configure(width=1344, height=750)
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(First)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

class First(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        l = [[1,2,3],[4,5,6]]
        Second().add_to_tree(l)
        tk.Button(self, text='add', command=lambda: controller.show_frame(Second)).pack()


class Second(tk.Frame):
    def __init__(self, parent=None, controller=None):
        tk.Frame.__init__(self, parent)
        self.bill_tree1 = ttk.Treeview(self, show='tree')
        tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree1.yview)

        self.bill_tree1.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
        self.bill_tree1.column("#0", stretch='no', minwidth=0, width=0)
        self.bill_tree1.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
        self.bill_tree1.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
        self.bill_tree1.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

        tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
        self.bill_tree1.place(relx=0.013,rely=0.185, width=780, height=301)

        # tk.Button(self, text='add 1', command=self.add).grid()


    def add(self):
        self.bill_tree1.insert('','end', values=('value 1','value 2','value 3'))

    def add_to_tree(self, i):
        self.bill_tree1.insert('','end', values=(i))

if __name__ == "__main__":
    app = Home()
    app.geometry('1300x700')
    app.mainloop()

我需要将数据发送到二等舱

【问题讨论】:

  • 语句 Second().add_to_tree(i) 创建了一个 Second 的实例,它创建了一个 Treeview 然后它向它添加了一些东西循环的每次迭代所以有一堆正在创建的单独的Treeview 小部件彼此无关。您需要创建一个 Treeview 小部件并在其中插入多个项目 - 所以也许应该只在循环外创建一个 Second 实例。
  • @martineau 先生,我尝试了您的建议,将代码更改为 l = [] for c in self.bill_tree.get_children(): l.append(self.bill_tree.item(c)['values']) Second().add_to_tree(l) 然后通过循环插入 add_to_code 但不起作用
  • 对不起,我真的看不懂。但是,您似乎仍在创建 Second 类的多个实例。如果您编辑了您的问题并提供了一个可运行的minimal reproducible example (MRE),那将是最好的。
  • 您只需创建一次实例s = Second(),然后将其作为参数发送到其他类 - First(s)def __init__(self, s): self.s = sself.s.add_to_tree(i)
  • 先生,请检查我的问题,我添加了我的项目的迷你版

标签: python tkinter treeview


【解决方案1】:

您没有创建最少的工作代码,所以我将使用我的示例代码。


您只需创建一次Second() 并将其作为参数发送到First(),它应该在变量中记住它并使用它。

# --- classes ---

class First():

 def __init__(self, second):
    
     self.second = second

     for c in self.bill_tree.get_children():
         i = self.bill_tree.item(c)['values']
         self.second.add_to_tree(i)

# --- main ---

s = Second()

f = First(s)

最少的工作代码:

import tkinter as tk
import tkinter.ttk as ttk

# --- classes ---

class First(tk.Frame):

 def __init__(self, master, second, **kwargs):
     super().__init__(master, **kwargs)
     
     self.second = second
     
     self.bill_tree = ttk.Treeview(self, show='tree')
     
     tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree.yview)

     self.bill_tree.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
     self.bill_tree.column("#0", stretch='no', minwidth=0, width=0)
     self.bill_tree.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
     self.bill_tree.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
     self.bill_tree.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

     tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
     self.bill_tree.place(relx=0.013,rely=0.185, width=780, height=301)

 def add(self):
     self.bill_tree.insert('','end', values=('value 1','value 2','value 3'))

 def add_to_tree(self, i):
     self.bill_tree.insert('','end', values=(i))

 def copy(self):
     for c in self.bill_tree.get_children():
         i = self.bill_tree.item(c)['values']
         self.second.add_to_tree(i)
   
class Second(tk.Frame):
    
 def __init__(self, master, **kwargs):
     super().__init__(master, **kwargs)

     self.bill_tree1 = ttk.Treeview(self, show='tree')
     
     tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree1.yview)

     self.bill_tree1.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
     self.bill_tree1.column("#0", stretch='no', minwidth=0, width=0)
     self.bill_tree1.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
     self.bill_tree1.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
     self.bill_tree1.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

     tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
     self.bill_tree1.place(relx=0.013,rely=0.185, width=780, height=301)

 def add(self):
     self.bill_tree1.insert('','end', values=('value 1','value 2','value 3'))

 def add_to_tree(self, i):
     self.bill_tree1.insert('','end', values=(i))
   
# --- main ---
                                                                    
root = tk.Tk()

s = Second(root, width=300, height=100)
s.pack(fill='both', expand=True)
s.add()

f = First(root, s, width=300, height=100)
f.pack(fill='both', expand=True)
f.add()
f.add()

button = tk.Button(root, text='Copy All', command=f.copy)
button.pack()

root.mainloop()

如果主窗口是类对象,SecondFirst 是此类中的元素

self.s = Second(self)
self.f = First(self)

那么First将使用self.master访问主窗口并使用self.master.s访问Second


最少的工作代码:

import tkinter as tk
import tkinter.ttk as ttk

# --- classes ---

class First(tk.Frame):

 def __init__(self, master, **kwargs):
     super().__init__(master, **kwargs)
     
     self.bill_tree = ttk.Treeview(self, show='tree')
     
     tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree.yview)

     self.bill_tree.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
     self.bill_tree.column("#0", stretch='no', minwidth=0, width=0)
     self.bill_tree.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
     self.bill_tree.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
     self.bill_tree.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

     tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
     self.bill_tree.place(relx=0.013,rely=0.185, width=780, height=301)

 def add(self):
     self.bill_tree.insert('','end', values=('value 1','value 2','value 3'))

 def add_to_tree(self, i):
     self.bill_tree.insert('','end', values=(i))

 def copy(self):
     for c in self.bill_tree.get_children():
         i = self.bill_tree.item(c)['values']
         self.master.s.add_to_tree(i)
   
class Second(tk.Frame):
    
 def __init__(self, master, **kwargs):
     super().__init__(master, **kwargs)

     self.bill_tree1 = ttk.Treeview(self, show='tree')
     
     tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree1.yview)

     self.bill_tree1.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
     self.bill_tree1.column("#0", stretch='no', minwidth=0, width=0)
     self.bill_tree1.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
     self.bill_tree1.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
     self.bill_tree1.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

     tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
     self.bill_tree1.place(relx=0.013,rely=0.185, width=780, height=301)

 def add(self):
     self.bill_tree1.insert('','end', values=('value 1','value 2','value 3'))

 def add_to_tree(self, i):
     self.bill_tree1.insert('','end', values=(i))
   
# --- main ---
                                                                    
root = tk.Tk()

root.s = Second(root, width=300, height=100)
root.s.pack(fill='both', expand=True)
root.s.add()

root.f = First(root, width=300, height=100)
root.f.pack(fill='both', expand=True)
root.f.add()
root.f.add()

button = tk.Button(root, text='Copy All', command=root.f.copy)
button.pack()

root.mainloop()

编辑:

在你的新例子中你必须使用

  • Homeself.frames[Second],而不是Second()

  • Firstcontroller.frames[Second] 而不是Second()

最少的工作代码

from tkinter import ttk, messagebox
import tkinter as tk

class Home(tk.Tk):    
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)

        container.pack(fill='both', expand=True)

        l = [[1,2,3],[4,5,6]]
        #Second().add_to_tree(l)

        self.frames = {}

        for F in (Second, First):
            frame = F(container, self)
            self.frames[F] = frame
            frame.configure(width=1344, height=750)
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(First)

        # has to be after loop which create `Second()`
        self.frames[Second].add_to_tree(l)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

class First(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        
        # it is good to keep it as class variable to use it in other functions in class
        self.controller = controller
        
        l = [[1,2,3],[4,5,6]]
        
        #Second().add_to_tree(l)
        self.controller.frames[Second].add_to_tree(l)
        
        tk.Button(self, text='add', command=lambda: controller.show_frame(Second)).pack()


class Second(tk.Frame):
    def __init__(self, parent=None, controller=None):
        tk.Frame.__init__(self, parent)

        # it is good to keep it as class variable to use it in other functions in class
        self.controller = controller
        
        self.bill_tree1 = ttk.Treeview(self, show='tree')
        tree_scroll_y = tk.Scrollbar(self, orient='vertical', command=self.bill_tree1.yview)

        self.bill_tree1.config(yscrollcommand=tree_scroll_y.set, columns=('#0','#1','#2','#3'))
        self.bill_tree1.column("#0", stretch='no', minwidth=0, width=0)
        self.bill_tree1.column("#1", stretch='no', minwidth=0, width=40, anchor='center')
        self.bill_tree1.column("#2", stretch='no', minwidth=0, width=180, anchor='w')
        self.bill_tree1.column("#3", stretch='no', minwidth=0, width=90, anchor='center')

        tree_scroll_y.place(relx=0.578, rely=0.186,width=20, height=299)
        self.bill_tree1.place(relx=0.013,rely=0.185, width=780, height=301)

        # tk.Button(self, text='add 1', command=self.add).grid()


    def add(self):
        self.bill_tree1.insert('','end', values=('value 1','value 2','value 3'))

    def add_to_tree(self, i):
        self.bill_tree1.insert('','end', values=(i))

if __name__ == "__main__":
    app = Home()
    app.geometry('1300x700')
    app.mainloop()

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 2012-04-25
    • 2016-07-07
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 2012-08-05
    相关资源
    最近更新 更多