如何在 Tkinter GUI 中停止并重新启动 python 线程?

How do I stop and restart a python thread within Tkinter GUI?

import tkinter as tk
import tkinter.font
import threading 

def sensor_4():
    i = 0
    while True: 
         i+=1

t4 = threading.Thread(target=sensor_4)

mainwindow = tk.Tk()

HEIGHT = 700
WIDTH = 800

canvas = tk.Canvas(mainwindow, height = HEIGHT, width = WIDTH)
canvas.pack()

frame = tk.Frame(mainwindow, bg='#08030D')  #inside box
frame.place(relx=0, rely=0.1, relwidth = 0.95, relheight = 0.6)

start_sensor4=tk.Button(frame, text = "Press to Start 4", bg='#292230',fg='white',command = t4.start)
start_sensor4.place(relx=0, rely=0.24, relwidth = 0.2, relheight = 0.05)

mainwindow.mainloop()

在代码示例中,我可以通过在 Tkinter GUI 中按下按钮来启动线程函数。我想知道如何在不必 return 的情况下退出线程函数,然后通过单击同一个按钮或单独的按钮重新启动线程。 我还收到错误消息,指出如果我单击启动按钮,线程只能启动一次。

棘手的部分在这里:“没有函数必须 return”。这意味着普通的 thread.join() 调用将挂起,因为线程必须做的工作没有尽头。我们必须使用 threading.Event() class 来实现这样的结果:

def sensor_4(running_event):
    i = 0
    while running_event.is_set():
         i+=1

def manage_thread(thread, running_event):
    if thread.is_alive():
        running_event.clear()
        thread.join()
    else:
        running_event.set()
        thread.start()

running_event = threading.Event()
t4 = threading.Thread(target=sensor_4, args=(running_event,))
..
..
start_sensor4=tk.Button(frame, text = "Press to Start 4", bg='#292230',fg='white',command = lambda: manage_thread(t4, running_event))
..

这并没有解决多次启动线程的问题,只是解决了使用按钮启动和停止的问题,而函数不必 return。要重新启动线程(如 thread.start()),您必须创建一个具有相同参数的新线程。

我认为“答案”在很大程度上取决于您如何定义您试图解决的设计问题,以及您如何提出问题。

答案似乎解决了您有关停止和重新启动线程的问题。

阅读“字里行间”的内容是不同的。

我认为,根据您的代码,您的设计问题是暂停线程,这与停止和重新启动有很大不同。

@Tresdon 给出了有关线程和异常的讨论的参考。当处于异常状态时,线程还没有死,除非它是未处理的。 ref'd 讨论指出线程已分配资源,一旦被杀死(解除分配),它不是重新启动而是需要新的创建。

要暂停线程,您只需要一个可以在线程代码中读取并由您的主代码切换的标志。如果设置,线程可以“等待”,如果没有设置线程代码运行。根据其他设计标准,等待片段可以是睡眠,或其他可能消耗更多或更少资源的暂停机制。