【问题标题】:Can't destroy inherited tkinter.Tk() window无法销毁继承的 tkinter.Tk() 窗口
【发布时间】:2018-08-17 04:23:55
【问题描述】:

我在杀死使用以下方式创建的 tkinter 窗口时遇到了很多麻烦。我收到如下所示的错误。我对 Python 还很陌生,因此我们将不胜感激。

class InspectWindow(tk.Frame):
    def __init__(self, sender_email, recipient_email, email_body, 
                   master = None):
        super().__init__(master)
        self.create_widgets()

def create_widgets(self):
    self.yes = tk.Button(self)
    self.yes['text'] = 'send me!'
    self.yes['command'] = self.send_email()

def send_email(self):
    root.destroy()


root = tk.Tk()
popup = InspectWindow(sender_email, recipient_email, email_body,
                        master=root)
popup.mainloop()



Traceback (most recent call last):
  File "spam.py", line 108, in <module>
    master=root)
  File "spam.py", line 16, in __init__
    self.create_widgets()
  File "AutomateFellowshipEmails.py", line 23, in create_widgets
    self.yes['command'] = self.send_email()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1486, in __setitem__
    self.configure({key: value})
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1479, in configure
    return self._configure('configure', cnf, kw)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1470, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!inspectwindow.!button"

【问题讨论】:

    标签: python-3.x inheritance tkinter destroy


    【解决方案1】:

    问题出在这行代码:

    self.yes['command'] = self.send_email()
    

    就像你这样做一样:

    result = self.send_email()
    self.yes['command'] = reuslt
    

    由于self.send_email()破坏了根窗口,然后返回None,所以和这样做是一样的:

    root.destroy()
    self.yes['command'] = None
    

    一旦您销毁了根窗口小部件——这会导致所有其他窗口小部件被销毁——您在尝试调用窗口小部件上的方法时都会收到错误消息。当您尝试配置 self.yes 时,self.yes 不再存在,因此您会收到错误消息。

    解决方案是将 reference 传递给按钮的功能,这样您就不会立即调用它。你这样做:

    self.yes['command'] = self.send_email
    

    请注意self.send_email 上缺少括号。您不是立即调用该函数,而是告诉 tk“这是我希望您在用户单击按钮时调用的函数的名称”。

    【讨论】:

    • 啊,我明白了。这很有意义,并且完全解决了问题。非常感谢。
    【解决方案2】:

    您必须保留 master 的引用才能调用其上的方法。
    (还有一些其他错误)

    类似的东西(我删除了未定义的变量mail,等等...)

    import tkinter as tk
    
    class InspectWindow(tk.Frame):          # if this is a popup, you may like to inherit from tk.TopLevel?
    
        def __init__(self, master = None):  # removed undefined variables, you can put them back in
            self.master = master            # keep a reference of master
            super().__init__(self.master)
            self.create_widgets()
            self.pack()                     # pack into parent window
    
        def create_widgets(self):
            self.yes = tk.Button(self)
            self.yes['text'] = 'send me!'
            self.yes['command'] = self.send_email   # removed () call, this takes a method, not a method call
            self.yes.pack()                 # pack into self
    
        def send_email(self):
            self.master.destroy()           # call destroy on self.master
                                            # maybe you want to call on self instead, depending what you want to destroy
    
    
    root = tk.Tk()
    popup = InspectWindow(master=root)      # removed undefined variables, you can put them back in
    popup.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2020-02-22
      • 2011-01-18
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 2014-06-12
      相关资源
      最近更新 更多