【发布时间】:2019-01-28 10:31:46
【问题描述】:
我正在尝试学习如何使用类构建 tkinter GUI 应用程序。除此之外,我还试图复制一个简单的类似游戏的 GUI,其中确实希望在每个窗口中都有一个完全不同的菜单,而不是顶层。所以我想做的是__init__我的班级通过创建我将要使用的所有小部件然后在窗口之间跳转时忘记并根据窗口放置它们。
问题:我无法在使用类时重现上述行为。
我创建了两个示例程序来说明问题。在第一个中,两个窗口之间的切换工作正常,程序复制了我期望的行为:
import tkinter as tk
import tkinter.ttk as ttk
def forget_widgets():
for widget in root.winfo_children():
widget.pack_forget()
def window1():
forget_widgets()
my_frame1.pack()
my_button1.grid(row=0, column=0)
my_button2.grid(row=1, column=0)
def window2():
forget_widgets()
my_frame2.pack()
my_button3.grid(row=0, column=0)
my_button4.grid(row=1, column=0)
if __name__ == '__main__':
root = tk.Tk()
my_frame1 = ttk.Frame(root)
my_frame2 = ttk.Frame(root)
my_button1 = ttk.Button(my_frame1, text='Button1', command=window2)
my_button2 = ttk.Button(my_frame1, text='Button2', command=window2)
my_button3 = ttk.Button(my_frame2, text='Button3', command=window1)
my_button4 = ttk.Button(my_frame2, text='Button4', command=window1)
window1()
root.mainloop()
但是,当我尝试将所有这些包装在一个类中时 - GUI 在切换到窗口 2 后停止工作。按钮似乎失去了它们的回调。代码:
import tkinter as tk
import tkinter.ttk as ttk
class App:
def __init__(self, master=None):
self.frame = ttk.Frame(master)
self.button1 = ttk.Button(self.frame, text='Button1', command=self.window2)
self.button2 = ttk.Button(self.frame, text='Button2', command=self.window2)
self.button3 = ttk.Button(self.frame, text='Button3', command=self.window1)
self.button4 = ttk.Button(self.frame, text='Button4', command=self.window1)
self.window1()
def window1(self):
self.widget_forget()
self.frame.pack()
self.button1.grid(column=0, row=0)
self.button2.grid(column=0, row=1)
def window2(self):
self.widget_forget()
self.frame.pack()
self.button3.grid(column=0, row=0)
self.button4.grid(column=0, row=1)
@staticmethod
def widget_forget():
for widget in root.winfo_children():
widget.pack_forget()
if __name__ == '__main__':
root = tk.Tk()
App(master=root)
root.mainloop()
我认为这个问题与我对类如何工作的理解有关。我对编程还是比较陌生,所以我可能缺少一些简单的东西。
我已经尝试以多种方式重组我的widget_forget() 函数,在 App 类之外定义它,使用 lambdas 创建回调,但没有任何积极影响。
起初我认为问题可能在于我只在根对象上使用forget(),但情况似乎并非如此,因为示例 1 工作正常并且其中的按钮以相同的方式定义.
我在堆栈上找到了一些答案,这些答案指向了一些其他可能的解决方案(即切换框架或使用 Toplevel 小部件),但我没有遇到与我自己类似的问题。
【问题讨论】:
-
在您的第一个示例中,您有
my_frame1和my_frame2。在第二个示例中,您只有self.frame。为什么在第二个示例中没有两个框架? -
实际上,添加第二帧解决了我的问题!所以谢谢。也许你可以解释一下,为什么程序不能在同一个框架下工作?是不是因为我把小部件放在第二个框架上,即使我忘记了框架,它们也会留在那儿?
-
我试图在我刚刚发布的答案中解释它,希望这会有所帮助!
标签: python-3.x class tkinter