【问题标题】:TclError: can't invoke "destroy" command: application has been destroyedTclError:无法调用“destroy”命令:应用程序已被销毁
【发布时间】:2016-06-11 17:26:06
【问题描述】:

我是 python 初学者。尝试制作一个新按钮来关闭窗口。我收到错误消息:

Tkinter 回调异常 Traceback(最近一次通话最后一次):文件 "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", 第 1536 行,在 call 中 return self.func(*args) 文件“tk_cp_successful.py”,第 138 行,在 buttonPushed self.root.destroy() 文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”, 第 1859 行,在销毁中 self.tk.call('destroy', self._w) TclError: can't invoke "destroy" command: application has been destroy

class LoginPage(tk.Frame):
   def __init__(self, parent, controller):
      self.controller = controller
      self.root = tk.Tk()
      global entry_1
      global entry_2
      tk.Frame.__init__(self, parent)
      label = tk.Label(self, text="Welcome to VISA Login Page",fg="blue")
      label.pack(pady=10,padx=10)

      label_1 = Label(self, text="Username")
      label_1.pack()
      label_2 = Label(self, text="Password")
      label_2.pack()
      entry_1 = Entry(self)
      entry_1.pack()
      entry_2 = Entry(self, show="*")
      entry_2.pack()
      label_1.grid(row=0, sticky=E)
      label_1.pack()
      label_2.grid(row=1, sticky=E)
      label_2.pack()
      entry_1.grid(row=0, column=1)
      entry_1.pack()
      entry_2.grid(row=1, column=1)
      entry_2.pack()
      checkbox = Checkbutton(self, text="Keep me logged in")

      checkbox.grid(columnspan=2)
      checkbox.pack()
      logbtn = Button(self, text="Login", command = self._login_btn_clickked)
      logbtn.grid(columnspan=2)
      logbtn.pack()
      myButton = Button(self, text="Exit",command = self.buttonPushed)
      myButton.pack()

  def buttonPushed(self):
      self.root.destroy()

  def _login_btn_clickked(self):
      #print("Clicked")
      username = entry_1.get()
      password = entry_2.get()

      #print(username, password)

      if username == "test" and password == "test":
          #box.showinfo("Login info", "Welcome Tester")
          button1 = ttk.Button(self, text="Please click, Welcome to login!!!",
                     command=lambda: self.controller.show_frame(StartPage))
          button1.pack()
      else:
          box.showerror("Login failed", "Incorrect username")

【问题讨论】:

  • 我从来没有见过这个:logbtn.grid(columnspan=2); logbtn.pack(),也就是说,“网格化”一个小部件并在“打包”它之后立即。我不知道真正的效果是什么,但我几乎可以肯定这不是“正确”的做法。
  • 感谢您的帮助。我可以在不破坏的情况下运行它。一切正常。一旦我运行 buttonPushed,它就会出错。感觉root是全局的,不能从这个类中使用--------.self.root.destroy()

标签: python python-2.7 tkinter


【解决方案1】:

你的代码有很多问题

  1. 缩进错误
  2. 混合grid()pack()
  3. 你是import tkinter as tk 还是from tkinter import *,即
    self.root = tk.Tk() (import as tk) 还是
    label_1 = Label(self, text="Username") (from tkinter import *)
  4. 程序中没有mainloop
  5. 在类中使用 global 是不必要的,而且风格很差

无论如何,以下修改后的代码都会运行,希望它会有所帮助。

import sys
if sys.version_info[0] < 3:
    import Tkinter as tk     ## Python 2.x
else:
    import tkinter as tk     ## Python 3.x

class LoginPage():
   def __init__(self):
      self.root=tk.Tk()
      label = tk.Label(self.root, text="Welcome to VISA Login Page",fg="blue")
      label.grid(row=0)

      label_1 = tk.Label(self.root, text="Username")
      label_2 = tk.Label(self.root, text="Password")
      self.entry_1 = tk.Entry(self.root)
      self.entry_2 = tk.Entry(self.root, show="*")
      label_1.grid(row=1, sticky="e")
      label_2.grid(row=2, sticky="e")
      self.entry_1.grid(row=1, column=1)
      self.entry_2.grid(row=2, column=1)

      ## doesn't do anything at this time
      ##checkbox = tk.Checkbutton(self.root, text="Keep me logged in")
      ##checkbox.grid(row=3, columnspan=2)

      logbtn = tk.Button(self.root, text="Login", command = self._login_btn_clickked)
      logbtn.grid(row=9, columnspan=2)
      myButton = tk.Button(self.root, text="Exit",command = self.buttonPushed)
      myButton.grid(row=10)

      self.root.mainloop()

   def buttonPushed(self):
      self.root.destroy()

   def _login_btn_clickked(self):
      #print("Clicked")
      username = self.entry_1.get()
      password = self.entry_2.get()

      #print(username, password)

      if username == "test" and password == "test":
          print "OK login"
          #box.showinfo("Login info", "Welcome Tester")
          #button1 = ttk.Button(self.root, text="Please click, Welcome to login!!!",
          #           command=lambda: self.controller.show_frame(StartPage))
          #button1.pack()
      else:
          #box.showerror("Login failed", "Incorrect username")
          print "Error"

LP=LoginPage()

【讨论】:

    【解决方案2】:

    忽略您的代码的所有其他问题,前几天我遇到了同样的问题。当你调用self.root.destroy() 时,Tkinter 将退出root.mainloop。然后在你打电话给root.mainloop 的地方之后,你可能会打电话给root.destroy。这意味着您试图破坏两次,这就是导致错误的原因。解决此问题的一种方法是让Exception 静默通过(尽管通常这不是好的做法):

    try:
        root.destroy()
    except:
        pass
    

    我可能错了,但这是我能想象的唯一导致此错误的原因。

    【讨论】:

      【解决方案3】:

      如果适用,root.quit() 可能会修复错误。

      【讨论】:

        【解决方案4】:

        当您有 2 个以上的主循环时,通常会发生此错误。 无外乎:

        import sys
        

        然后创建一个按钮退出:

        B=tk.Button(self.root,text="quit",command=lambda:sys.exit())
        B.grid()
        

        【讨论】:

          【解决方案5】:

          你需要销毁 def,因为它们会不断重复。使用 "your def".destroy() 来防止发生此错误。我遇到过同样的问题。它是对我造成它的 def 之一,并在 if 声明中销毁此 def 解决了我的问题

          【讨论】:

            【解决方案6】:

            如果你错误地销毁了一个已经销毁或尚未创建的根窗口,就会出现这种错误

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-06-17
              • 2019-06-15
              • 2017-12-31
              • 2014-03-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多