gpt4 book ai didi

python - 使用 threading 和 tkinter 模块在 python 中停止线程并避免 'RuntimeError' 的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-03 12:43:56 29 4
gpt4 key购买 nike

我在网上浏览了多种解决方案,但它们需要大量代码,一旦你扩大规模,这些代码可能会让人感到困惑。有没有一种简单的方法来停止线程并避免 RuntimeError: threads can only be started once ,以便无限次调用线程。这是我的代码的简单版本:

import tkinter
import time
import threading

def func():

entry.config(state='disabled')
label.configure(text="Standby for seconds")
time.sleep(3)
sum = 0
for i in range(int(entry.get())):
time.sleep(0.5)
sum = sum+i
label.configure(text=str(sum))
entry.config(state='normal')

mainwindow = tkinter.Tk()
mainwindow.title('Sum up to any number')

entry = tkinter.Entry(mainwindow)
entry.pack()
label = tkinter.Label(mainwindow, text = "Enter an integer",font=("Arial",33))
label.pack()

print(entry.get())

button = tkinter.Button(mainwindow, text="Press me", command=threading.Thread(target=func).start)
button.pack()

最佳答案

可以从其他线程调用对 tkinter 小部件的修改,一旦主线程可用,它们就会立即发生,这可能会立即发生。如果调用修改的后台线程休眠而主线程仅在 mainloop ,我们可以模拟应用程序的暂停,而不会像问题的目标那样阻塞主线程。

然后我们可以继承 Thread生成一个运行自己的循环并保持 started 的线程即使在它的目标完成之后,我们也可以随意调用它的目标。我们甚至可以通过使用 daemon 将后台线程上发生的错误传递并优雅地退出线程而不挂起应用程序。模式和 try - except堵塞。

BooleanVar thread.do充当一个开关,我们可以在 lambda 中设置它运行 func一次在 threadbutton被按下。这在主线程和后台线程之间实现了一个廉价的消息传递系统,我们可以用很少的额外代码扩展它以允许调用 func带有参数并从中返回值。

import threading, time, tkinter, sys

class ImmortalThread(threading.Thread):
def __init__(self, func):
super().__init__(daemon=True)
self.func = func
self.do = tkinter.BooleanVar()
def run(self):
while True:
if self.do.get():
try:
self.func()
self.do.set(False)
except:
print("Exception on", self, ":", sys.exc_info())
raise SystemExit()
else:
# keeps the thread running no-ops so it doesn't strip
time.sleep(0.01)

def func():
entry.config(state='disabled')
label.configure(text="Standby for seconds")
time.sleep(3)
sum = 0
for i in range(int(entry.get())):
time.sleep(0.5)
sum = sum+i
label.configure(text=str(sum))
entry.config(state='normal')

mainwindow = tkinter.Tk()
mainwindow.title("Sum up to any number")

entry = tkinter.Entry(mainwindow)
entry.pack()
label = tkinter.Label(mainwindow, text="Enter an integer", font=("Arial", 33))
label.pack()

thread = ImmortalThread(func)
thread.start()
button = tkinter.Button(mainwindow, text="Press me", command=lambda: thread.do.set(True))
button.pack()

mainwindow.mainloop()

关于python - 使用 threading 和 tkinter 模块在 python 中停止线程并避免 'RuntimeError' 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62351129/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com