【发布时间】:2021-02-15 21:34:09
【问题描述】:
我正在使用应该是下载管理器的 tkinter 和 urllib 制作这个应用程序,并决定为每次下载使用 multiprocessing,但是,我遇到了问题.每次我点击“下载”按钮从我的小部件中获取信息以开始下载时,我都会收到 名称错误,说我的小部件未定义。 我尝试将小部件设为全局,甚至在我的函数中全局调用小部件,甚至将它们作为参数传递,但显然它们都不起作用。我认为这可能与我的程序结构有关,所以我在一个更简单的模拟程序上对其进行了测试,但仍然出现相同的错误。为什么会这样?模拟程序:
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
【问题讨论】:
-
tkinter 小部件不能跨进程共享。改用线程。
-
谢谢@acw1668,但实际上我在多处理之前尝试了线程。我切换到多处理的原因是因为
terminate()函数。我尝试在线程中使用事件进行相互通信来告诉线程何时启动和停止,但显然它不适用于urllib.request.urlretrieve()。如果您知道我可以停止 urlretrieve 线程的任何方法,请告诉我! -
您可以将回调分配给
urlretrieve()的reporthook选项。在回调中,您可以根据全局标志引发异常以中止下载。当然你最好在运行urlretrieve()时使用try/except。 -
Here 是一个使用
reporthook回调来中止下载的简单示例。
标签: python tkinter multiprocessing python-multiprocessing nameerror