获取数据并使用 tkinter 使用"start"和"stop"按钮绘制数据



我希望我的程序在按下";"开始";按钮时;暂停";按钮,我停止我的程序。这里的问题是,当我按下";"开始";,它工作(我可以看到我的图表(,但我不能按下";暂停";按钮(它会一直刷新(。请参阅下面的代码。

谢谢你的帮助!

"""
Created on Tue Nov 16 17:38:33 2021
@author: admin
"""

import serial
import struct
import platform
import multiprocessing
import time
import numpy as np
import csv
# from pylab import *
import matplotlib.pyplot as plt
import tkinter

class MeasurementConverter:
def convertValue(self, bytes):
pass

class ForceMeasurementConverterKG(MeasurementConverter):
def __init__(self, F_n, S_n, u_e):
self.F_n = F_n
self.S_n = S_n
self.u_e = u_e
def convertValue(self, value):
A = struct.unpack('>H', value)[0]
# return (A - 0x8000) * (self.F_n / self.S_n) * (self.u_e / 0x8000)
return self.F_n / self.S_n * ((A - 0x8000) / 0x8000) * self.u_e * 2

class GSV3USB:
def __init__(self, com_port, baudrate=38400):
com_path = f'/dev/ttyUSB{com_port}' if platform.system(
) == 'Linux' else f'COM{com_port}'
# print(f'Using COM: {com_path}')
self.sensor = serial.Serial(com_path, baudrate)
self.converter = ForceMeasurementConverterKG(10, 0.499552, 2)

def read_value(self):
self.sensor.read_until(b'xA5')
read_val = self.sensor.read(2)
return self.converter.convertValue(read_val)

# GSV3USB(6).sensor.close()


# initialization of datas
gsv_data=[]
temps=[]
t_0=time.time()
def stop():
window.poll = False

def data_gsv():
dev = GSV3USB(6)
# fig=plt.figure()
# ax = fig.add_subplot(111)
i=0
# line1, = ax.plot(temps, gsv_data)

while window.poll:

gsv_data.append(dev.read_value())
t1=time.time()-t_0
temps.append(t1)


# I can print the datas without noticing any lags
# print(dev.read_value())   
# I cannot plot the datas without noticing any lags
plt.plot(temps,gsv_data)
plt.draw ()
plt.axis([temps[i]-6,temps[i]+6,-2,10])
plt.pause(0.00000001)
plt.clf()
# plt.close()
i=i+1
# I cannot pause without noticing any lags
# time.sleep(0.0001)
# print(dev.read_value())   

# # I cannot save datas without noticing any lags
# with open('student_gsv.csv', 'w') as f: 
#     write = csv.writer(f) 
#     write.writerow(gsv_data)                 

else:

print("Stopped long running process.")
return

window = tkinter.Tk()
window.poll = True
window.title("Loop")
startButton = tkinter.Button(window, text = "Start", command = data_gsv)
stopButton = tkinter.Button(window, text = "Pause", command = stop)
startButton.pack()
stopButton.pack()
window.mainloop()``` 

Tkinter主循环被while循环阻塞,并且这里从未调用停止按钮操作。重复单击停止按钮会导致整个GUI冻结。避免这种情况的一种选择是使用threading模块。数据读取循环可以在不同的线程中执行,并且可以从GUI启动或停止,而不会出现很多问题。

import threading
t1 = threading.Thread(target=data_gsv, args=())
.
.
.
def start():
t1.start()
.
.
.
startButton = tkinter.Button(window, text = "Start", command = start)  # data_gsv -> start

现在,停止按钮没有冻结,并停止循环。这是一个基本的解决方案,请随时根据需要进行修改。点击此处阅读更多关于线程的信息:

Real Python.com官方文件

相关内容