我目前正在开发带有GUI的程序,以从传感器收集数据并在GUI中可视化它。 来自传感器的数据存储在列表中,以供进一步计算。
我当前正在尝试做的是在新线程中启动日志记录过程。 这应该可以防止GUI冻结。
我当前的代码:
import tkinter as tk
import time
import threading
class GUI:
def __init__(self, tk_object):
self.gui = tk_object
self.gui.title("Logger")
self.gui.resizable(width=True, height=True)
self.testlabel = tk.Label(self.gui, text="Recording in process")
self.testlabel.grid(row = 7, column = 0)
self.testlabel.config(bg='white')
btn1 = tk.Button(master, text="Start Recording", width=16, height=5, command=lambda: self.start_functions())
btn1.grid(row=2,column=0)
btn2 = tk.Button(master, text="Stop Recording", width=16, height=5, command=lambda: self.stop_functions())
btn2.grid(row=3,column=0)
def start_functions(self):
"""Calls the method get_sample in a new thread and changes the bg-color of the label to red"""
Thread_1 = threading.Thread(target=self.get_sample(), name='Thread1')
Thread_1.start()
self.testlabel.config(bg='red')
def stop_functions(self):
"""Stops all active threads and changes bg-color of the label back to white"""
#stop_threads = threading.Event()
#stop_threads.set()
threading.Event().set()
self.testlabel.config(bg='white')
def get_sample(self):
"""get data and append it to a list"""
while not threading.Event().is_set():
time.sleep(1)
res_cel.append(res_cel[-1]+1)
x_value.append(x_value[-1]+1)
print(res_cel)
print(x_value)
master = tk.Tk()
master_object = GUI(master)
master.mainloop()
当前,get_sample
方法包含一个占位符。
我试图通过get_sample
处理程序停止Thread1(运行Event()
方法的地方)。
while not threading.Event().is_set():
这似乎无法正常工作。
有更好的方法可以做到这一点吗?
在采用这种方法之前,我尝试使用class
处理线程(这是在stackoverflow上找到的,但是对不起,我似乎再也找不到它了):
class Controller(object):
def __init__(self):
self.thread1 = None
self.stop_threads = Event()
def run(self):
.. do somehting
并通过以下方式启动/停止线程:
def starting_thread(self):
self.stop_threads.clear()
self.thread1 = Thread(target = self.run)
self.thread1.start()
def stopping_thread(self):
self.stop_threads.set()
self.thread1 = None
注意:这些函数在Controller
类中。
使用此解决方案,我无法更改GUI
类中的标签背景颜色,因为它不知道它所引用的对象。
我对python编程还很陌生,所以如果有人可以向我解释我在这里缺少的内容,我会很高兴。
谢谢 xSaturn
答案 0 :(得分:1)
您最好创建自己的Thread对象,并带有一种方法来停止它。当线程使用其run方法时,它将停止运行。看下面的例子
import time
import tkinter as tk
from threading import Thread
class MyThread(Thread):
thread_running = False
def run(self):
k = 0
self.thread_running = True
while self.thread_running:
print(k)
k +=1
time.sleep(1)
print("thread ended")
def stop(self):
self.thread_running = False
class Window(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.thread = None
tk.Button(self, text="launch thread", command=self.launch_thread)\
.grid(row=1, column=0)
tk.Button(self, text="stop thread", command=self.stop_thread)\
.grid(row=2, column=0)
def launch_thread(self):
if self.thread:
print("thread already launched")
else:
print("thread launched")
self.thread = MyThread()
self.thread.start()
def stop_thread(self):
if self.thread:
self.thread.stop()
self.thread = None
else:
print("no thread running")
if __name__ == '__main__':
win = Window()
win.mainloop()
有关更多信息,请参阅本主题。 Is there any way to kill a Thread?