【问题标题】:Acquire data and plot them with a "start" and "stop" button using tkinter使用 tkinter 获取数据并使用“开始”和“停止”按钮绘制它们
【发布时间】:2021-11-16 17:50:15
【问题描述】:

我希望我的程序在我按下“开始”按钮后立即从力传感器获取和绘制数据,当我按下“暂停”按钮时,我会停止我的程序。这里的问题是,当我按下“开始”时,它可以工作(我可以看到我的图表)但我无法按下“暂停”按钮(它一直在刷新)。请看下面我的代码。

感谢您的帮助!

"""
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()``` 

【问题讨论】:

  • 不要使用while 循环,它会阻止mainloop 更新

标签: python loops tkinter


【解决方案1】:

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 Official Documentation

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2014-01-21
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
相关资源
最近更新 更多