我正在尝试使用tkinter
制作Python GUI,我需要一个菜单项来打开主窗口的另一个副本。我试着做下面的代码,当我运行程序时,它冻结了一点,然后打开了大量的窗口。打印的最后一条错误消息如下。
我有两个问题。
TheThing
类的实例? (在IDLE中,File > New File
有我正在寻找的行为。)为什么会发生这种错误?
RecursionError: maximum recursion depth exceeded while calling a Python object
我的代码:
import tkinter as tk
class TheThing:
def __init__(self, root):
root.option_add('*tearOff', False)
menubar = tk.Menu(root)
root.config(menu = menubar)
file = tk.Menu(menubar)
menubar.add_cascade(menu = file, label = "File")
file.add_command(label = 'New', command = doathing())
def doathing():
thing1 = tk.Tk()
thing2 = TheThing(thing1)
def main():
win = tk.Tk()
do = TheThing(win)
win.mainloop()
if __name__ == '__main__': main()
我已经找到了答案的地方:
This question似乎有一个非常类似的问题。我或许能够研究并找到解决方案,但我仍然无法理解这个问题。
This question是关于recursion,python和tkinter的,但似乎更多的是after
。
答案 0 :(得分:2)
问题出在这一行:
file.add_command(label = 'New', command = doathing())
在这里,您执行 doathing
回调,然后尝试将其结果(None
)绑定到命令。在这种特定情况下,这也会导致无限递归,因为回调将创建一个新的帧实例,它将再次执行回调,这将创建另一个帧,依此类推。您必须将函数本身绑定到命令,而不是调用该函数。
file.add_command(label = 'New', command = doathing) # no ()
如果您需要将参数传递给该函数(这里不是这种情况),您可以使用lambda
:
file.add_command(label = 'New', command = lambda: doathing(params))
此外,您可能只需在回调中创建一个Toplevel
实例,而不是创建另一个Tk
实例,即
def doathing():
thing1 = tk.Toplevel()
thing2 = TheThing(thing1)