Как остановить и перезапустить поток python в Tkinter GUI? - PullRequest
0 голосов
/ 21 июня 2020
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. Мне интересно, как я могу выйти из функции потока без необходимости возврата функции и перезапустить поток, нажав ту же кнопку или, возможно, отдельную кнопку. Я также получаю сообщение об ошибке, в котором говорится, что потоки можно запустить только один раз, если я нажму кнопку запуска.

1 Ответ

1 голос
/ 21 июня 2020

Сложная часть здесь: «без возврата функции». Это означает, что ванильный вызов thread.join() просто зависнет, поскольку работа, которую должен выполнять поток, не имеет конца. Мы должны использовать класс threading.Event(), чтобы получить такой результат:

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))
..

Это не решает проблему запуска потока более одного раза, а только запускает и останавливает с помощью кнопки без функции, имеющей возвращаться. Чтобы перезапустить поток (как в thread.start ()), вы должны создать новый поток с теми же параметрами.

...