2016-02-28 148 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()