Python 为什么在初始化新进程时会出现名称错误?
我正在使用tkinter和urllib制作这个应用程序,这应该是一个下载管理器,并决定对每次下载使用多处理,但是,我遇到了一个问题。每次我点击“下载”按钮从我的小部件获取信息开始下载时,我都会收到一个名称错误,说我的小部件没有定义我尝试将小部件设置为全局,甚至在函数中全局调用小部件,甚至将它们作为参数传递,但显然没有一个有效。我认为这可能与我的程序的结构有关,所以我在一个模拟程序上测试了它,这个程序简单得多,但仍然有相同的错误。为什么会这样?模拟程序:Python 为什么在初始化新进程时会出现名称错误?,python,tkinter,multiprocessing,python-multiprocessing,nameerror,Python,Tkinter,Multiprocessing,Python Multiprocessing,Nameerror,我正在使用tkinter和urllib制作这个应用程序,这应该是一个下载管理器,并决定对每次下载使用多处理,但是,我遇到了一个问题。每次我点击“下载”按钮从我的小部件获取信息开始下载时,我都会收到一个名称错误,说我的小部件没有定义我尝试将小部件设置为全局,甚至在函数中全局调用小部件,甚至将它们作为参数传递,但显然没有一个有效。我认为这可能与我的程序的结构有关,所以我在一个模拟程序上测试了它,这个程序简单得多,但仍然有相同的错误。为什么会这样?模拟程序: from tkinter import *
from tkinter import *
from multiprocessing import Process
times_clicked = 0
def change_lbl():
global times_clicked
times_clicked += 1
lbl.config(text=f"Clicked: {times_clicked}")
if __name__ == '__main__':
root = Tk()
root.geometry("300x300")
lbl = Label(root, text="Waiting for clicks...")
def start():
Process(target=change_lbl, daemon=True).start()
btn = Button(root, text="Add to clicks...", command=start)
lbl.pack(pady=10)
btn.pack()
root.mainloop()
错误:
Process Process-1:
Traceback (most recent call last):
File "C:\Users\Family\AppData\Local\Programs\Python\Python38-32\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "C:\Users\Family\AppData\Local\Programs\Python\Python38-32\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Family\PycharmProjects\8-bit Downloader\pyfile.py", line 10, in change_lbl
lbl.config(text=f"Clicked: {times_clicked}")
NameError: name 'lbl' is not defined
您必须定义
lbl
编写如下代码
lbl=#你需要的东西
tkinter小部件不能跨进程共享。使用线程代替。谢谢,@acw1668,但实际上我在多重处理之前尝试过线程。我切换到多处理的原因是terminate()
函数。我尝试在线程间通信中使用事件来告诉线程何时开始和停止,但显然它不适用于urllib.request.urlretrieve()
。请如果你知道任何方法,我可以停止urlretrieve线程让我知道!您可以将回调分配给urlretrieve()
的reporthook
选项。在回调内部,您可以基于全局标志引发异常以中止下载。当然,您最好在运行urlretrieve()
时使用try/except。是一个使用reporthook
回调中止下载的简单示例。您好,@Oliver Hnat。谢谢你的建议,但似乎不起作用。我试过了,看起来我也必须重新定义整个根,所以我认为这不是最好的方法。