为什么Tkinter应用程序在调用退出后无法关闭

时间:2018-07-22 17:18:53

标签: python tkinter

我正在用tkinter开发一个应用程序。它由几个框架(窗口)组成,一个框架放在另一个框架上。我可以使用一个按钮从一个窗口传递到另一个窗口。我以在堆栈溢出的情况下看到的示例为基础构建了该示例,但是我无法回忆起指向它的链接。

我怀疑由于做出此选择,因此在调用self.quit()方法后,tkinter无法正确关闭。 下面的示例是我的应用程序的简化版,尽管它的结构与完整的应用程序相同。

使用下面的代码,您可以看到应用程序在整个程序结束前(即我放置的延迟时间为10秒)不会关闭。

import tkinter as tk
import tkinter.ttk as ttk
import time


class App:
    """
    Inherited from the Frame class
    """

    def __init__(self):
        self.root = tk.Tk()
        self.root.title('Test')

        # This frame will contain all windows
        container = ttk.Frame(self.root)
        container.pack(side="top", fill="both", expand=True)

        # Create different pages/windows of the application
        self.frames = {}
        self.frames["Window1"] = Window1(parent=container, controller=self)
        self.frames["Window2"] = Window2(parent=container, controller=self)
        self.frames["Window3"] = Window3(parent=container, controller=self)

        self.frames["Window1"].grid(row=0, column=0, sticky="nsew")
        self.frames["Window2"].grid(row=0, column=0, sticky="nsew")
        self.frames["Window3"].grid(row=0, column=0, sticky="nsew")

        self.show_frame("Window1")

    def run(self):
        self.root.deiconify
        self.root.mainloop()

    def show_frame(self, page_name):
        '''
        Show a frame for the given page name
        '''
        frame = self.frames[page_name]
        frame.tkraise()


class Window1(ttk.Frame):
    def __init__(self, parent, controller):
        ttk.Frame.__init__(self, parent)
        self.controller = controller
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # Go to window 2
        self.buttonW2 = ttk.Button(self, text='Go to 2', command=lambda: controller.show_frame("Window2"))
        self.buttonW2.grid(row=0, column=0, sticky='NSE')

        # Go to window 3
        self.buttonW3 = ttk.Button(self, text='Go to 3', command=lambda: controller.show_frame("Window3"))
        self.buttonW3.grid(row=0, column=1, sticky='NSE')

        # EXIT button
        self.buttonExit = ttk.Button(self, text='Exit', command=self.quit)
        self.buttonExit.grid(row=0, column=2, sticky='NSE')


class Window2(ttk.Frame):
    def __init__(self, parent, controller):
        ttk.Frame.__init__(self, parent)
        self.controller = controller
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        # Go back button
        buttonBack = ttk.Button(self, text="Back to 1", command=lambda: controller.show_frame("Window1"))
        buttonBack.grid(row=0, column=3, sticky="NSE")


class Window3(ttk.Frame):
    def __init__(self, parent, controller):
        ttk.Frame.__init__(self, parent)
        self.controller = controller
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        # Go back button
        buttonBack = ttk.Button(self, text="Back to 1", command=lambda: controller.show_frame("Window1"))
        buttonBack.grid(row=1, column=1, sticky="E")


if __name__ == '__main__':
    app = App()
    app.run()

    print('The App should be closed')

    time.sleep(10)

    print('The App is now closed')

有人可以帮我吗?

谢谢

1 个答案:

答案 0 :(得分:1)

Tkinters quit命令只会停止mainloop,但不会破坏窗口。如果要删除窗口,请使用destroy

因此创建退出按钮,如下所示:

    self.buttonExit = ttk.Button(self, text='Exit', command=self.controller.root.destroy)
    self.buttonExit.grid(row=0, column=2, sticky='NSE')