2016-02-28 133 views
1

我是一名python初学者。尝试制作一个新按钮来关闭窗口。我得到的错误信息:TclError:无法调用“销毁”命令:应用程序已被销毁

Exception in Tkinter callback Traceback (most recent call last): File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in call return self.func(*args) File "tk_cp_successful.py", line 138, in buttonPushed self.root.destroy() File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1859, in destroy self.tk.call('destroy', self._w) TclError: can't invoke "destroy" command: application has been destroyed

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") 
+0

我从来没有见过这样的:'logbtn.grid(columnspan = 2); logbtn.pack()',也就是“夹持”一个小部件并在“打包”之后立即执行。我不知道什么是真正的效果,但我几乎可以肯定,这不是“正确”的做法。 – nbro

+0

感谢您的帮助。我可以在不破坏的情况下运行它。一切正常。一旦我运行buttonPressed,它会得到错误。感觉根是全球性的,它不能从这个类中使用--------。self.root.destroy() – jack

回答

2

有很多问题,你的代码

  1. 缩进错误
  2. 混合grid()pack()
  3. import tkinter as tkfrom tkinter import *,即
    self.root = tk.Tk()import as tk)或
    label_1 = Label(self, text="Username")from tkinter import *
  4. 程序
  5. 利用全球的一类无mainloop是没有必要的,风格差

在任何情况下,以下修改后的代码运行,所以希望它会帮帮我。

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 

我可能是错的,但是这是我能想象是造成此错误的唯一的事情。

0

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

1

当您有超过2个主循环时,通常会发生此错误。 做无非就是:

import sys 

,然后创建一个按钮来退出:

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