Python Tkinter使用菜单栏命令无意递归…原因?

Python Tkinter使用菜单栏命令无意递归…原因?,python,recursion,tkinter,Python,Recursion,Tkinter,我正在尝试使用tkinter制作一个Python GUI,我需要一个菜单项来打开主窗口的另一个副本。我尝试执行以下代码,当我运行该程序时,它冻结了一段时间,然后打开了大量窗口。打印的最后一条错误消息如下 我有两个问题 我如何才能完成让“新建”按钮打开一个新窗口和TheThing类实例的任务?(在空闲状态下,File>newfile具有我正在寻找的行为。) 为什么会发生这种错误 RecursionError:调用Python对象时超出了最大递归深度 我的代码: import tkinter as

我正在尝试使用
tkinter
制作一个Python GUI,我需要一个菜单项来打开主窗口的另一个副本。我尝试执行以下代码,当我运行该程序时,它冻结了一段时间,然后打开了大量窗口。打印的最后一条错误消息如下

我有两个问题

  • 我如何才能完成让“新建”按钮打开一个新窗口和
    TheThing
    类实例的任务?(在空闲状态下,
    File>newfile
    具有我正在寻找的行为。)
  • 为什么会发生这种错误

    RecursionError:调用Python对象时超出了最大递归深度
    
  • 我的代码:

    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()
    
    我已经找到答案的地方:

    • 看起来它有一个非常相似的问题。我也许能够研究这个问题并找到解决方案,但我仍然不理解这个问题

    • 是关于递归、python和tkinter,但似乎更多的是关于
      之后的
      事情


      • 问题出在这一行:

            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))
        

        另外,您不应该创建另一个
        Tk
        实例,而应该在回调中创建一个实例,即

        def doathing():
            thing1 = tk.Toplevel()
            thing2 = TheThing(thing1)
        

        command=doathing()
        正在立即执行回调(并在回调中以无休止的递归方式创建一个新窗口),并将其结果绑定到
        命令
        参数。卸下
        ()
        。还有,那该怎么办?这就解决了。我删除了
        ()
        ,它似乎可以正常工作。它应该打开一个新窗口,就像旧窗口一样。Python空闲文本编辑器在
        File>newfile
        下具有此行为。谢谢,谢谢。你的回答非常有用。你不仅回答了我问的问题,而且在阅读你的答案时,你还回答了很多我想知道的问题。