Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3 Tkinter messagebox复制循环_Python_Python 3.x_Tkinter - Fatal编程技术网

Python 3 Tkinter messagebox复制循环

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

我最近开始学习python并编写一些简单的程序,通过stack overflow和YouTube教程,一切都很顺利。然而,当我尝试创建一个Tkinter“WM_DELETE_WINDOW”协议并运行该程序时。文本框将正常打开,并使用“退出”文本框正确关闭,但第二个空文本框和第二个“退出”文本框将使用相同的消息打开。然后在我关闭后,程序会尝试第三次破坏这个盒子,并得到这个错误

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)