【问题标题】:Tkinter: update TopLevel window when closing another TopLevel window above first? (Reference?)Tkinter:首先关闭上面的另一个 TopLevel 窗口时更新 TopLevel 窗口? (参考?)
【发布时间】:2016-07-14 20:28:53
【问题描述】:

我是一个 python 初学者,正在制作一个程序,该程序应该保存和显示露营地的预订(只是为了好玩......)。我以 OOP 方式对其进行了结构化,这意味着我为每个单独的窗口定义了一个类。当另一个 TopLevel 窗口(从 Subwindow2 创建)关闭时,我需要做的是更新一个显示数据库条目的 TopLevel 窗口(SubWindow2)。

import Tkinter as tk

class MenuWindow(tk.Tk):
    def __init__(self, master):
        self.master = master

        #Widgets

    def open_subwindow1(self):
       self.window = Toplevel(self.master)
       self.SubSubWindow1 = SubSubWindow1(self.window)

    def open_subwindow2(self):
       self.window = Toplevel(self.master)
       self.SubSubWindow2 = SubSubWindow2(self.window)

class SubWindow1(tk.Tk):
    def __init__(self, master):
         self.master = master

         #Widgets

class Subwindow2(tk.TopLevel):
    def __init__(self, master):
         self.master = master

         #Widgets

         self.button = tk.Button(master, text='Quit', command=open_subsub1)

    def load_values(self):
        #loading sqlite db-values into listboxes

    def open_subsub1(self):
        self.window = Toplevel(self.master)
        self.SubSubWindow1 = SubSubWindow1(self.window)

class SubSubWindow1(tk.TopLevel):
    def __init__(self, master):
        self.master = master

        #Widgets

        self.button = tk.Button(master, text='Quit', command=on_quit)

    def on_quit(self):
        #Here I want to call a function that updates SubWindow2 (loads sqlite database values into several listboxes)

        self.master.destroy()

root = tk.Tk()
myprog = MyProg(root)

root.mainloop()

如何从 SubSubWindow1 访问 Subwindow2 中的函数? self.master 仅指 TopLevel() 实例,对吗?

def on_quit(self):
    self.SubWindow2.load_values()
    self.master.destroy()

不起作用,我得到一个TypeError: unbound method load_values() must be called with SubWindow2 instance as first argument (got nothing instead)

这是“嵌套”TopLevel-windows 的无效方法吗?有什么办法?

任何评论都非常感谢!感谢您的帮助

【问题讨论】:

    标签: python python-2.7 tkinter


    【解决方案1】:

    我应该先声明我也是一个新手,我非常感谢其他人的建议,以免传播错误信息。

    据我所知,您对 Python 中继承与封装的工作方式存在一些误解。首先,在 Tkinter 应用程序中,应该只有一个 Tk() 实例。在您的类定义中,您声明...

    class SubWindow1(tk.Tk):
    

    这意味着每当你创建一个新的 SubWindow1 时,一个新的 Tk 实例将被它实例化,并且 SubWindow1 将继承它的所有属性。

    如果您想创建一个引用 Toplevel 实例并具有所有属性的类,那么您的 Subwindow2 是正确的。

    class Subwindow2(tk.TopLevel):
    

    但是,在 init 中,您还必须像这样初始化这个 Toplevel 实例:

    class SubWindow2(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self)
            self.master = master
    

    每个 'master' 指的是它上面的元素。 Tk 应用程序作为树层次结构工作。这就是为什么你应该只有一个 Tk() 实例,它作为你的“根”。这个 Tk 实例在其中包含窗口,其中包含窗口或元素。因此,每个窗口或元素都有一个父级,称为主控,因此您将能够四处导航。

    因此,当您创建 SubWindow2 的实例时,this 指的是您的 SubWindow2 中的所有内容,以及包含在 Toplevel 实例中的所有内容。因为'self'现在指的是一个Toplevel,你可以将它传递给孩子成为主人,就像这样:

    self.sub_sub_window1 = SubSubWindow1(self)
    

    self.master 仅指 TopLevel() 实例对吗?

    是的,但是由于您将通过 SubWindow2 继承继承所有 Toplevel 属性,因此您可以添加更多方法并仍然通过您的 self.master 标记引用它们。

    最后,您还应该对希望在窗口上正确显示的元素调用 pack()。

    总的来说,我对您的程序进行了一些编辑,以尝试演示继承的一些概念以及它在 Tkinter 应用程序中的工作方式。我希望你能看看这个并从中得到一些东西。如果您不同意任何元素,请告诉我,因为它远非完美。

    import Tkinter as tk
    
    class MenuWindow():
        def __init__(self, master):
            self.master = master
            self.sub_window_1 = SubWindow1(self.master)
            self.sub_window_2 = SubWindow2(self.master)
    
    class SubWindow1(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self)
            self.master = master
    
    class SubWindow2(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self)
            self.master = master
            self.sub_sub_window1 = SubSubWindow1(self)
    
        def print_hello(self):
            print "Hello!"
    
    class SubSubWindow1(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self)
            self.master = master
            self.button = tk.Button(self.master, text='Say Hello & Destroy', command=self.on_quit)
            self.button.pack()
    
        def on_quit(self):
            self.master.print_hello()
            self.master.destroy()
    
    root = tk.Tk()
    myprog = MenuWindow(root)
    root.mainloop()
    

    【讨论】:

    • 哇,这个作品太棒了! Alltough我不得不使用“自我”作为我的小部件(即框架)的父级,以便它们显示在顶部窗口而不是根窗口中!感谢您的帮助和努力
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2016-12-07
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    相关资源
    最近更新 更多