PyQt 每 5 秒更新一次文本框 [英] Have textbox update every 5 seconds PyQt

查看:144
本文介绍了PyQt 每 5 秒更新一次文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以这是我的问题,我有来自串行电缆的数据每 5 秒读取一次并存储在 CSV 文件中.我也将这些数据放入一个列表中.我想要做的是获取变量 5、7 和 9,并将它们显示在我有 Qtextboxes 的 GUI 中……我该怎么做?

So here is my problem, I have data from a serial cable being read every 5 seconds and being stored on a CSV file. I am also taking that data and making it into a list. What I would like to do is take variables 5, 7, and 9 and have them be displayed in my GUI where I have Qtextboxes... how do I do that?

变量列表将位于称为列表值的值中.我想调用 5、7 和 9 并让它们显示在我的 PyQt 窗口中各自的文本框中.

The list of variables will be in a value known as listvalues. I want to call 5, 7, and 9 and have them display in their respective text boxes in my PyQt window.

这是我的代码:

from PyQt4 import QtGui
import sys
import masimo
import csv
import time
import datetime as DT
import threading
from threading import Thread
import serial
import os

os.chdir(r"C:\Users\SpO2\Desktop\Data")
time = time.strftime("%d %b %Y %H%M%S")
location = r'%s.csv' % time
outputfile = open(location, mode='x', newline='')
outputWriter = csv.writer(outputfile)
outputWriter.writerow(["start"])
outputfile.close()
port = "COM4"


class ExampleApp(QtGui.QMainWindow, masimo.Ui_MainWindow):
    def __init__(self, parent=None):
        super(self.__class__, self).__init__()
        self.setupUi(self)

def SerialRead():
    delay1 = DT.datetime.now()                
    ser = serial.Serial(port, baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)   
    out = ser.read(167)
    reading = str(out)
    plaintext1 = reading.replace(' ', ', ')
    plaintext = plaintext1.replace('=', ', ')
    listvalue = plaintext.split(", ")
    ser.close()

    outputfile = open(location, mode='a', newline='')
    outputWriter = csv.writer(outputfile)
    outputWriter.writerow([plaintext])
    outputfile.close()

    delay2 = DT.datetime.now()
    differencetime = (delay2 - delay1).total_seconds()
    writedelay = int(5)
    restart = (writedelay - differencetime)
    threading.Timer(restart, SerialRead).start() 

def main():
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp()
    QtGui.QApplication.processEvents()
    form.show()
    app.exec_()    

if __name__ == '__main__':
    Thread(target = SerialRead).start()
    Thread(target = main).start()

推荐答案

我认为你可以做以下两件事之一:

I would think you could do one of two things:

  1. 在窗口中使用 QTimer,将其间隔设置为 5 秒,然后将方法连接到其超时信号,并更新该方法中的文本字段.
  2. 使用在您的窗口之间共享的线程事件以及您的读取过程,并在您的窗口类中使用 QTimer,它会更频繁地检查事件是否已设置并在设置时进行更新.
  1. Use a QTimer in your window, set its interval to 5 seconds and connect a method to its timeout signal, and update your text fields within that method.
  2. Use a threading event that is shared between your window and your read process and use a QTimer in your window class that checks more frequently to see if the event is set and do the update when it is.

我可能会使用一个事件,以便您知道线程正在休眠,并且您不会在线程写入值时尝试读取它们.

I would probably use an event so that you know that the thread is sleeping and you aren't trying to read values while the thread is writing them.

在您的 ExampleApp 类中,您需要存储事件并处理超时:

In your ExampleApp class, you would need to store the event and handle the timeouts:

class ExampleApp(QtGui.QMainWindow, masimo.Ui_MainWindow):
    def __init__(self, event, parent=None):
        super(self.__class__, self).__init__()
        self.setupUi(self) 
        self.dataWasReadEvent = event

        self.checkThreadTimer = QtCore.QTimer(self)
        self.checkThreadTimer.setInterval(500) #.5 seconds

        self.checkThreadTimer.timeout.connect(self.readListValues)

    def readListValues(self):
        if self.dataWasReadEvent.is_set():
            #Read your events from the list and update your fields

            self.dataWasReadEvent.clear() #Clear the event set flag so that nothing happens the next time the timer times out

您的 SerialRead 函数需要采用线程事件的参数,并且需要在串行读取之后但在重新启动之前设置该事件:

Your SerialRead function would need to take an argument that is the threading event and the event would need to be set after the serial read but before the restart:

def SerialRead(dataReadEvent):
    ...
    dataReadEvent.set()
    threading.Timer(restart, SerialRead, args=(dataReadEvent,)).start()

您的 main 函数还需要接受要传递给 ExampleApp 的初始化程序的事件参数:

Your main function will also need to accept an event argument to be passed to the initializer for ExampleApp:

def main(dataReadEvent):
    ...
    form = ExampleApp(dataReadEvent)

最后,在您的 if __name__ == '__main__': 部分,需要创建线程事件并将其传递给 Thread 调用:

And finally, in your if __name__ == '__main__': section, the threading event would need to be created and passed to the Thread calls:

if __name__ == '__main__':
    dataReadEvent = threading.Event()
    Thread(target = SerialRead, args=(dataReadEvent,) ).start()
    Thread(target = main, args=(dataReadEvent,) ).start()

这篇关于PyQt 每 5 秒更新一次文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆