Python 3 Tkinter messagebox复制循环
我最近开始学习python并编写一些简单的程序,通过stack overflow和YouTube教程,一切都很顺利。然而,当我尝试创建一个Tkinter“WM_DELETE_WINDOW”协议并运行该程序时。文本框将正常打开,并使用“退出”文本框正确关闭,但第二个空文本框和第二个“退出”文本框将使用相同的消息打开。然后在我关闭后,程序会尝试第三次破坏这个盒子,并得到这个错误Python 3 Tkinter messagebox复制循环,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我最近开始学习python并编写一些简单的程序,通过stack overflow和YouTube教程,一切都很顺利。然而,当我尝试创建一个Tkinter“WM_DELETE_WINDOW”协议并运行该程序时。文本框将正常打开,并使用“退出”文本框正确关闭,但第二个空文本框和第二个“退出”文本框将使用相同的消息打开。然后在我关闭后,程序会尝试第三次破坏这个盒子,并得到这个错误 C:\Users\thech\Desktop\Python stuff>python spam.py Traceba
C:\Users\thech\Desktop\Python stuff>python spam.py
Traceback (most recent call last):
File "spam.py", line 34, in <module>
spam()
File "spam.py", line 31, in spam
if closed():
File "spam.py", line 13, in closed
mibox.destroy()
File "C:\Users\thech\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2062, in destroy
self.tk.call('destroy', self._w)
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed
问题是:当用户单击X按钮时,操作系统会自动调用函数
closed
。Tkinter(以及其他GUI系统)的属性是,您的程序由创建“事件”的用户操作驱动,这会导致环境调用您的“事件处理程序”。在您的例子中,函数closed
是一个处理程序,事件是单击X
当代码到达函数mainloop
时,它不会立即返回。相反,程序会等待用户事件。当这些用户事件中的一个导致tk根对象被销毁时(在您的例子中是mibox.destroy()
),对mainloop的调用会立即返回。这里再次调用closed()
。这将导致对话框再次出现。tk环境必须打开一个空tk窗口,才能将此对话框附加到其中。这就是为什么会看到第二个对话框和第二个窗口。问题是对closed()的显式调用
我修改了你的程序,现在可以用了。我还做了一些其他的改变。我将全局变量声明移到了最外层的缩进级别——我不喜欢在函数内部创建全局变量,这使得代码很难理解。在closed
函数中需要一个全局语句;否则Python将生成同名的局部变量,而不是修改全局变量。我还会在最后打印全局值,不管它是否为真
如果这不起作用,请致电1-800-273-8255寻求帮助
from tkinter import *
from tkinter import messagebox
spamreturn = False
#pop up
def spam():
def closed():
global spamreturn
if messagebox.askokcancel("Quit", "Do you really wish to quit?"):
spamreturn = True
mibox.destroy()
mibox = Tk()
topframe = Frame(mibox)
miLabel = Label(mibox, text="Call 1-800-273-8255")
mibutton = Button(topframe, text="Your Computer has been infected")
mibutton2 = Button(topframe, text="Please call 1-800-273-8255 for Assistance")
miLabel.pack()
mibutton.pack()
mibutton2.pack()
topframe.pack()
mibox.geometry("300x100+500+250")
mibox.protocol("WM_DELETE_WINDOW", closed)
mibox.mainloop()
spam()
print(spamreturn)
只需删除/注释掉
if closed():
和spamreturn=True
,它将根据需要工作,并使closed()函数再次执行
from tkinter import *
from tkinter import messagebox
spamreturn = False
#pop up
def spam():
def closed():
global spamreturn
if messagebox.askokcancel("Quit", "Do you really wish to quit?"):
spamreturn = True
mibox.destroy()
mibox = Tk()
topframe = Frame(mibox)
miLabel = Label(mibox, text="Call 1-800-273-8255")
mibutton = Button(topframe, text="Your Computer has been infected")
mibutton2 = Button(topframe, text="Please call 1-800-273-8255 for Assistance")
miLabel.pack()
mibutton.pack()
mibutton2.pack()
topframe.pack()
mibox.geometry("300x100+500+250")
mibox.protocol("WM_DELETE_WINDOW", closed)
mibox.mainloop()
spam()
print(spamreturn)