即使root被杀死,python顶层也会运行

时间:2018-07-17 15:50:18

标签: python tkinter toplevel

我在下面包括了一些基本代码,这些代码生成一个框架,然后生成一个顶层以销毁自身。在第一个销毁后创建第二个。

运行此应用程序时,在第一个顶层正在等待时,如果单击主窗口上的“ X”,它将杀死自身和顶层,但是随后将创建第二个顶层以及一个通用的Tk()。关闭后,我得到一个错误:_tkinter.TclError: can't invoke "wm" command: application has been destroyed

我尝试使用root.destroy()quit()os._exit(),但是这些都不完全停止应用程序。在根窗口被破坏后,如何完全停止运行任何脚本?

from tkinter import *

class Application(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.L1 = Label(root,text='Hi!')
        self.L1.pack()

 def Window1():
     Wind1 = Toplevel()
     Wind1.geometry('100x100+100+100')
     Wind1.B1 = Button(Wind1,text='Close',command=Wind1.destroy)
     Wind1.B1.pack()
     Wind1.lift(aboveThis=root)
     Wind1.wait_window()

def Window2():
     Wind2 = Toplevel()
     Wind2.geometry('100x100+100+100')
     Wind2.B2 = Button(Wind2,text='Close',command=Wind2.destroy)
     Wind2.B2.pack()
     Wind2.lift(aboveThis=root)
     Wind2.wait_window()

def Close_Window():
    root.destroy()

root = Tk()
root.geometry('100x100+50+50')
root.protocol('WM_DELETE_WINDOW',Close_Window)
app = Application(root)
Window1()
Window2()
root.mainloop()

1 个答案:

答案 0 :(得分:1)

您的错误的确切原因是由2个问题引起的。一种是由于wait_window()方法而在启动时未创建两个窗口。另一个问题是缺少为Toplevel()窗口定义的父项。

看看下面的修改后的代码。 (请注意,此代码仍需要一些工作,但这是您需要更改以纠正错误的地方)

from tkinter import *

class Application(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.L1 = Label(root, text='Hi!')
        self.L1.pack()

def Window1():
    Wind1 = Toplevel(root)
    Wind1.geometry('100x100+100+100')
    Wind1.B1 = Button(Wind1,text='Close',command=Wind1.destroy)
    Wind1.B1.pack()
    Wind1.lift(aboveThis=root)
    #Wind1.wait_window()

def Window2():
    Wind2 = Toplevel(root)
    Wind2.geometry('100x100+100+100')
    Wind2.B2 = Button(Wind2,text='Close',command=Wind2.destroy)
    Wind2.B2.pack()
    Wind2.lift(aboveThis=root)
    #Wind2.wait_window()

def Close_Window():
    root.destroy()

root = Tk()
root.geometry('100x100+50+50')
root.protocol('WM_DELETE_WINDOW',Close_Window)
app = Application(root)
Window1()
Window2()
root.mainloop()

我认为您将所有内容移入课堂会从中受益更多。这样,您可以使用类属性来管理应用程序中的所有数据,包括从Toplevel()小部件中获得的数据。

import tkinter as tk


class Application(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.geometry('100x100+50+50')
        self.protocol('WM_DELETE_WINDOW', self.close_window)
        self.L1 = tk.Label(self, text='Hi!')
        self.L1.pack()
        tk.Button(self, text="Window 1", command=self.window1).pack()
        tk.Button(self, text="Window 2", command=self.window2).pack()

    def window1(self):
        wind1 = tk.Toplevel(self)
        wind1.geometry('100x100+100+100')
        wind1.B1 = tk.Button(wind1, text='Close', command=wind1.destroy).pack()

    def window2(self):
        wind2 = tk.Toplevel(self)
        wind2.geometry('100x100+100+100')
        wind2.B2 = tk.Button(wind2, text='Close', command=wind2.destroy).pack()

    def close_window(self):
        self.destroy()


app = Application()
app.mainloop()