2014-03-05 633 views
2

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

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

在此先感谢。

继承人一块代码....

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? 

回答

1

如果你把new_window到你的应用2,那么你应该罚款。

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。 Have a look at alternatives

当我开始使用Tkinter时,我很困惑quitdestroy

+0

我正在使用new_window代码段来启动App2。如果我将它移入App2,则App2不会启动。我觉得我可能会用错误的方式启动App2。 –

+0

我添加了一个新的方法来启动应用程序。 'App2.start_app()'有趣的想法让应用程序自行启动。我不会想到这一点。 – User

+0

对不起,但我现在失去了,新手综合征。不幸的是我迷惑了自己,我没有清楚地解释它。感谢您的建议和指向替代方案的链接。 –

1

在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循环。看看this answer使用Tk的函数在间隔后运行代码。如果在处理程序中调用另一个函数后重新计划另一个函数,那么可以安排一个定期运行的函数,并避免在不需要额外线程的情况下阻止事件处理。

+0

我见过很多像这样的例子,但是我看不出如何使它适合我的代码。我想我需要看看我如何开始新窗口,新窗口是从以前的课程开始的,我看到的例子都在一个课堂上。 –

相关问题