Python的Tkinter – closures一个退出button的子窗口

我有一个Piface适配器板的树莓派。 我已经做了一个GUI来控制Piface板上的LED。 在GUI上的一个button打开一个新的窗口,按下button,开始和停止运行一小段代码,使LED像Knight Riders汽车一样,在线程中使用While循环连续运行。 在这个新窗口中,我添加了一个EXITbutton。 我想添加一段代码,当我单击EXITbutton时将closures新窗口,然后返回到主窗口。 我查了很多例子,但是看不到我应该放什么或者在哪里。 我已经尝试了“退出”,但它closures了整个程序。 看了很多例子,我可能会以不正确的方式创build新窗口,所以请随时告诉我是否有更好的方法。

那么有没有更好的方法呢? 任何指针将不胜感激。

提前致谢。

这里有一段代码

def new_window(self): print('New Window') self.newWindow = tk.Toplevel(self.master) self.app = App2(self.newWindow) self.newWindow.grab_set() # I added this line to stop opening multiple new windows class App2: def __init__(self, master): frame = Frame(master) frame.pack() Label(frame, text='Turn LED ON').grid(row=0, column=0) Label(frame, text='Turn LED OFF').grid(row=0, column=1) self.button0 = Button(frame, text='Knight Rider OFF', command=self.convert0) self.button0.grid(row=2, column=0) self.LED0 = Label(frame, image=logo2) self.LED0.grid(row=2, column=1) self.button9 = Button(frame, text='Exit', command=self.close_window) self.button9.grid(row=3, column=0) def convert0(self, tog=[0]): tog[0] = not tog[0] if tog[0]: print('Knight Rider ON') self.button0.config(text='Knight Rider ON') t=threading.Thread(target=self.LED) t.start() self.signal = True #added to stop thread self.LED0.config(image = logo) else: print('Knight Rider OFF') self.button0.config(text='Knight Rider OFF') self.signal = False #added to stop thread self.LED0.config(image = logo2) def LED(self): while self.signal: #added to stop thread a=0 while self.signal: #added to stop thread pfio.digital_write(a,1) #turn on sleep(0.05) pfio.digital_write(a,0) #turn off sleep(0.05) a=a+1 if a==7: break while self.signal: #added to stop thread pfio.digital_write(a,1) #turn on sleep(0.05) pfio.digital_write(a,0) #turn off sleep(0.05) a=a-1 if a==0: break def close_window(self): print('Close Child window') #self.newWindow.destroy() Not sure what to put here? 

在Tk窗口使用销毁方法销毁。 所以如果你有一个对话框顶层,你想摆脱它,你可以调用它的destroy()方法。 或者你可以撤回它,在这种情况下,对象继续存在,但不再在屏幕上,并重新显示它deiconify()顶级框架。 尽管摧毁它们更为常见。 下面是创建和销毁子对话框的简单示例:

 import sys from Tkinter import * class App(Frame): def __init__(self, parent = None): Frame.__init__(self, parent) self.grid() self.button = Button(self, text = "Create Dialog", command=self.CreateDialog) self.button.grid() def CreateDialog(self): dialog = Toplevel(self) dialog.wm_title("Dialog window") dialog.wm_transient(self) dialog.wm_protocol("WM_DELETE_WINDOW", lambda: self.onDeleteChild(dialog)) button = Button(dialog, text="Close", command=lambda: self.onDeleteChild(dialog)) button.grid() def onDeleteChild(self, w): w.destroy() def main(): app = App() app.mainloop() if __name__ == "__main__": sys.exit(main()) 

你也应该考虑在代码中使用一个定时器来驱动LED环路,而不是一个while循环。 看看这个答案,使用Tk的函数后间隔运行代码。 如果在处理程序中调用另一个函数之后重新计划另一个函数,那么可以安排一个定期运行的函数,并避免阻塞事件处理而不需要额外的线程。

如果你把new_window放到你的App2中,那么你应该没问题。

 self.newWindow.destroy() 

破坏窗户。 这是正确的呼叫。 窗口关闭,窗口中的所有窗口小部件也被销毁。

quit()将停止mainloop()在这种情况下,程序结束在最后一行,也销毁一切。

你一定要使用destroy

 class App2: newWindow = None def close_window(self): print('Close Child window') if self.newWindow: try: self.newWindow.destroy() except (): pass # fill in the error here self.newWindow = None def new_window(self): print('New Window') self.close_window() self.newWindow = tk.Toplevel(self.master) self.app = App2(self.newWindow) self.newWindow.grab_set() @classmethod def start_app(cls): window = tk.Tk(self.master) app = App2(window) return app 

你不应该从线程访问Tkinter。 看看替代品

当我开始与Tkinter合作的时候,我也感到困惑不已。