PyQt 每 5 秒更新一次文本框
Have textbox update every 5 seconds PyQt
所以这是我的问题,我每 5 秒读取一次来自串行电缆的数据并将其存储在 CSV 文件中。我也正在获取这些数据并将其放入列表中。我想做的是获取变量 5、7 和 9,并将它们显示在我的 GUI 中,我的 GUI 中有 Qtextboxes...我该怎么做?
变量列表将在一个称为列表值的值中。我想调用 5、7 和 9,并让它们显示在我的 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()
我认为你可以做以下两件事之一:
- 在您的 window 中使用 QTimer,将其间隔设置为 5 秒并将方法连接到其超时信号,并在该方法中更新您的文本字段。
- 使用 window 和读取进程共享的 threading event,并在 window class 中使用 QTimer,它会更频繁地检查是否事件已设置并在设置时进行更新。
我可能会使用一个事件,以便您知道线程正在休眠,并且您不会在线程写入值时尝试读取值。
在您的 ExampleApp
class 中,您需要存储事件并处理超时:
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
函数需要采用线程事件作为参数,并且需要在串行读取之后但在重新启动之前设置该事件:
def SerialRead(dataReadEvent):
...
dataReadEvent.set()
threading.Timer(restart, SerialRead, args=(dataReadEvent,)).start()
您的 main
函数还需要接受要传递给 ExampleApp 的初始化程序的事件参数:
def main(dataReadEvent):
...
form = ExampleApp(dataReadEvent)
最后,在您的 if __name__ == '__main__':
部分中,需要创建线程事件并将其传递给线程调用:
if __name__ == '__main__':
dataReadEvent = threading.Event()
Thread(target = SerialRead, args=(dataReadEvent,) ).start()
Thread(target = main, args=(dataReadEvent,) ).start()
所以这是我的问题,我每 5 秒读取一次来自串行电缆的数据并将其存储在 CSV 文件中。我也正在获取这些数据并将其放入列表中。我想做的是获取变量 5、7 和 9,并将它们显示在我的 GUI 中,我的 GUI 中有 Qtextboxes...我该怎么做?
变量列表将在一个称为列表值的值中。我想调用 5、7 和 9,并让它们显示在我的 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()
我认为你可以做以下两件事之一:
- 在您的 window 中使用 QTimer,将其间隔设置为 5 秒并将方法连接到其超时信号,并在该方法中更新您的文本字段。
- 使用 window 和读取进程共享的 threading event,并在 window class 中使用 QTimer,它会更频繁地检查是否事件已设置并在设置时进行更新。
我可能会使用一个事件,以便您知道线程正在休眠,并且您不会在线程写入值时尝试读取值。
在您的 ExampleApp
class 中,您需要存储事件并处理超时:
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
函数需要采用线程事件作为参数,并且需要在串行读取之后但在重新启动之前设置该事件:
def SerialRead(dataReadEvent):
...
dataReadEvent.set()
threading.Timer(restart, SerialRead, args=(dataReadEvent,)).start()
您的 main
函数还需要接受要传递给 ExampleApp 的初始化程序的事件参数:
def main(dataReadEvent):
...
form = ExampleApp(dataReadEvent)
最后,在您的 if __name__ == '__main__':
部分中,需要创建线程事件并将其传递给线程调用:
if __name__ == '__main__':
dataReadEvent = threading.Event()
Thread(target = SerialRead, args=(dataReadEvent,) ).start()
Thread(target = main, args=(dataReadEvent,) ).start()