简体   繁体   English

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

[英]python toplevel runs even after root is killed

I've included some basic code below, which generates a frame, and then a toplevel made to destroy itself. 我在下面包括了一些基本代码,这些代码生成一个框架,然后生成一个顶层以销毁自身。 A second is created after the first is destroyed. 在第一个销毁后创建第二个。

When this application is run, while the first toplevel is waiting, if the 'X' on the main window is clicked, it kills itself and the toplevel, but then the second toplevel is created along with a generic Tk(). 当运行此应用程序时,在第一个顶层正在等待的情况下,如果单击主窗口上的“ X”,它将杀死自身和顶层,但随后将创建第二个顶层以及通用Tk()。 When that is closed I get an error: _tkinter.TclError: can't invoke "wm" command: application has been destroyed 当关闭该_tkinter.TclError: can't invoke "wm" command: application has been destroyed时,我得到一个错误: _tkinter.TclError: can't invoke "wm" command: application has been destroyed

I've tried using root.destroy() , quit() and os._exit() , but none of these completely stops the application. 我试过使用root.destroy()quit()os._exit() ,但是这些都没有完全停止应用程序。 What can be done to completely stop any script from running after the root window is destroyed? 在根窗口被破坏后,如何完全停止运行任何脚本?

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()

The exact reason for your error is caused by 2 problems. 您的错误的确切原因是由2个问题引起的。 One is that both windows are not being created at start up due to the wait_window() method. 一种是由于使用wait_window()方法而在启动时未创建两个窗口。 The other problem is the lack of a parent being defined for your Toplevel() windows. 另一个问题是缺少为您的Toplevel()窗口定义的父项。

Take a look at the below modified code. 看一下下面的修改后的代码。 (Note this code needs some work still but is what you need to change to fix the error) (请注意,此代码仍需要一些工作,但这是您需要更改以解决错误的方法)

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()

I think you would benifit more from moving everything into a class. 我认为您将所有内容移入课堂会从中受益更多。 This way you can use class attributes to manage all data within the application including those you get from Toplevel() widgets. 这样,您可以使用类属性来管理应用程序中的所有数据,包括从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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM