Python Tkinter-使用exit按钮关闭子窗口

2024-06-01 09:01:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个覆盆子皮与皮面适配器板。我做了一个图形用户界面来控制面板上的发光二极管。 图形用户界面上的一个按钮打开一个新窗口,按下一个按钮,启动和停止运行一小段代码,使LED像骑士骑士车一样,在一个线程中使用一个While循环,连续上下运行。 在这个新窗口中,我添加了一个退出按钮。我想添加一段代码,在单击“退出”按钮时关闭新窗口,然后返回主窗口。 我查了很多例子,但就是看不清应该放什么,放在哪里。我试过“退出”,但它关闭了整个程序。 看了很多例子后,我可能会以不太正确的方式创建我的新窗口,所以请随时告诉我是否有更好的方法。

有更好的方法吗?任何指点都将不胜感激。

提前谢谢。

这里有一段代码。。。。

   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?

Tags: totextselfaddedledsignaldefcolumn
2条回答

如果你把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。Have a look at alternatives

当我开始使用Tkinter时,我也被quitdestroy搞糊涂了。

在Tk中,使用destroy方法销毁窗口。因此,如果您有一个顶层的对话框,并且您想去掉它,就调用它的destroy()方法。或者您可以撤回它,在这种情况下,对象将继续存在,但不再在屏幕上,若要重新显示它,请将顶层框架神化。但更常见的是摧毁他们。下面是一个创建和销毁子对话框的简单示例:

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的after函数在间隔后运行代码。如果在处理程序中重新调度另一个after调用,则可以安排定期运行函数,避免在不需要额外线程的情况下阻塞事件处理。

相关问题 更多 >