Tkinter:首先关闭另一个TopLevel窗口时更新TopLevel窗口? (参考?)

时间:2016-07-14 20:28:53

标签: python python-2.7 tkinter

我是一个蟒蛇初学者制作一个程序,应该保存并为露营地提供预订(只是为了好玩......)。我以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)

这是"嵌套"无效的approch顶层窗口?什么是替代方案?

任何言论都非常受欢迎!谢谢你的帮助

1 个答案:

答案 0 :(得分:0)

我应该通过声称我也是一个新手来作为序言,我会非常感谢别人的建议,以免传播错误的信息。

从我所看到的,你对Python中的继承与封装如何工作有一些误解。首先,在Tkinter应用程序中,应该只有一个Tk()实例。在您的类定义中,您声明...

class SubWindow1(tk.Tk):

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

如果您想创建一个引用Toplevel实例且具有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()实例,它作为你的'root'。这个Tk实例包含其中的窗口,其中包含窗口或元素。因此,每个窗口或元素都有一个父节点,称为主节点,因此您可以导航。

因此,当您创建SubWindow2的实例时,这将引用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()