如何解决从 tkinter 中的按钮开始和停止线程中的重复任务
我想从 tkinter 制作的 GUI 开始一个任务,它应该每 10 秒运行一次。 GUI 有一个开始按钮和一个停止按钮,以及一个停止线程的事件。 我正在使用调度模块和线程以避免冻结 GUI。
from functools import partial
import tkinter as tk
from threading import Thread,Event,Lock
import schedule
import time
import os
class GUI():
def __init__(self,master):
self.master = master
self.frame = tk.Frame(self.master)
self.button1 = tk.Button(text='Start',command=partial(run_threaded,experiment),width=20,height=2,bg="gray",fg="black")
self.button1.pack()
self.button2 = tk.Button(text='Stop',command=stop_button,fg="black")
self.button2.pack()
def job():
print("Task started")
print("Task completed")
def experiment():
schedule.every(10).seconds.do(job)
while 1:
schedule.run_pending()
def run_threaded(job_func):
job_thread = Thread(target=job_func)
job_thread.start()
if stop_threads.is_set():
job_thread.join()
job_thread = None
def start_button():
run_threaded(experiment)
def stop_button():
global stop_threads
stop_threads.set()
def main():
global stop_threads
thread1=None
stop_threads = Event()
root = tk.Tk()
app = GUI(root)
root.mainloop()
if __name__ == '__main__':
main()
任务在 10 秒后开始并定期重复,但停止按钮不起作用,我希望该过程立即开始,没有最初的延迟。
此外,每隔一次我运行它时,任务就会启动,但 GUI 不会出现。
有没有更好的方法来实现这一点?
解决方法
尝试这样的事情:
import tkinter as tk
from time import sleep
from functools import partial
from threading import Thread
running_job = False
def job():
print("Task started")
print("Task completed")
def experiment():
while running_job:
job()
# I changed it to 1 sec to make it easier to test
sleep(1)
class GUI:
def __init__(self,master):
self.master = master
self.frame = tk.Frame(self.master)
command = partial(run_threaded,experiment)
self.button1 = tk.Button(text="Start",command=command)
self.button1.pack()
self.button2 = tk.Button(text="Stop",command=stop_button)
self.button2.pack()
def run_threaded(job_func):
global running_job
running_job = True
job_thread = Thread(target=job_func,daemon=True)
job_thread.start()
def stop_button():
global running_job
running_job = False
if __name__ == "__main__":
root = tk.Tk()
app = GUI(root)
root.mainloop()
它使用一个名为 running_job
的全局变量。当 running_job
为 True
时,while
内的 experiment
循环可以运行。当转向 False
时,experiment
停止。这种方法的问题在于,如果您在 tkinter
函数中使用 job
小部件/变量,tkinter 可能会崩溃。
另一种方法是使用 .after
脚本,但要使其正常工作,job
函数的执行时间不应太长。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。