如何使用来自USB串行(来自Arduino)的数据刷新/更新QLabel? [英] How do I refresh/update QLabel with data from USB serial (from Arduino)?

查看:91
本文介绍了如何使用来自USB串行(来自Arduino)的数据刷新/更新QLabel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是一个NOOB问题;对不起.我使用Arduino来控制计时,并使用RasPi进行车道位置(第1,第2,第3等)的GUI显示以及以秒为单位的运行时间(例如"2.1234).我在QT Creator中具有基本的shell GUI设置,并已成功连接Arduino&通过USB的RasPi.我还成功地将Arduino串行数据提取到RasPi(已通过单独的小型Python代码进行了测试).

I know this is a NOOB question; forgive me. I built a Pinewood Derby race timer (small car track) for Cub Scouts using a combination of an Arduino to control timing and RasPi for GUI display of lane place (1st, 2nd, 3rd, etc.) and run time in seconds (e.g. "2.1234"). I have the basic shell GUI setup in QT Creator and have successfully connected the Arduino & RasPi via USB. I am also successfully pulling the Arduino serial data into RasPi (tested with separate small Python code).

问题是,一旦Arduino通过USB触发竞赛结果字符串,GUI中的QLabels就会动态更新.换句话说,当比赛开始时,Arduino发送"B"作为开始(需要GUI清除以前的结果);当比赛结束时,Arduino发送"F",然后发送地点"1"以及时间"2.1234",我需要Python更新/更改每个车道位置和车道时间的QLabel.我敢肯定有一个简单的方法可以做到这一点,但是我无法找到如何搜索这个很棒的网站和其他网站.

Problem I am having is the dynamic update of the QLabels in the GUI once the Arduino fires the race result strings via USB. in other words, when a race starts the Arduino sends "B" for begin (need GUI to blank previous results); when race is finished, Arduino sends "F" and then sends place "1" along with time "2.1234" and I need Python to update/change respective QLabels for each lane place and lane time. I am sure there is an easy way to do this, but I am unable to find how via searching this awesome website and others.

非常感谢,对于接下来可能发生的FUBAR编码,我深表歉意!下面的示例仅显示一个车道,而一旦我弄清楚如何使用它,我将使用4倍车道.

Thanks much in advance and I apologize for what is probably FUBAR coding that follows! The sample below only shows one lane vs. the 4x lanes I will use once I figure out how to do this.

我正在使用两个Python代码:

与QT Creator生成的XML代码交互的Python代码:

import sys
import time
import serial

from PyQt4 import QtCore, QtGui, uic

global ser

ser=serial.Serial("/dev/ttyUSB1",115200)
ser.flushInput()

qtCreatorFile = "PinewoodDisplay.ui" # Enter file here.

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

while True:
    if ser.inWaiting()>0:
        inputValue = (ser.readline().strip())
        self.Lane1_Place.setText(inputValue)

从QT Creator生成的XML(不确定我是否要发布此权限)-文件名是"PinewoodDisplay.ui":

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>619</width>
    <height>1051</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="styleSheet">
   <string notr="true">background-color: rgb(102, 102, 108)</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QGroupBox" name="Lane1_Group">
    <property name="geometry">
     <rect>
      <x>50</x>
      <y>20</y>
      <width>481</width>
      <height>741</height>
     </rect>
    </property>
    <property name="cursor">
     <cursorShape>CrossCursor</cursorShape>
    </property>
    <property name="autoFillBackground">
     <bool>false</bool>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color : rgb(0, 75, 0)</string>
    </property>
    <property name="title">
     <string/>
    </property>
    <property name="alignment">
     <set>Qt::AlignHCenter|Qt::AlignTop</set>
    </property>
    <layout class="QGridLayout" name="gridLayout">
     <item row="2" column="0">
      <widget class="QLabel" name="Lane1_Place">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="palette">
        <palette>
         <active>
          <colorrole role="WindowText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Button">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Text">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="ButtonText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Base">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Window">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
         </active>
         <inactive>
          <colorrole role="WindowText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Button">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Text">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="ButtonText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Base">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Window">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
         </inactive>
         <disabled>
          <colorrole role="WindowText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Button">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Text">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="ButtonText">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>255</red>
             <green>255</green>
             <blue>255</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Base">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
          <colorrole role="Window">
           <brush brushstyle="SolidPattern">
            <color alpha="255">
             <red>0</red>
             <green>75</green>
             <blue>0</blue>
            </color>
           </brush>
          </colorrole>
         </disabled>
        </palette>
       </property>
       <property name="font">
        <font>
         <family>Gentium Book Basic</family>
         <pointsize>350</pointsize>
         <weight>75</weight>
         <bold>true</bold>
        </font>
       </property>
       <property name="autoFillBackground">
        <bool>false</bool>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgb(255, 255, 255)</string>
       </property>
       <property name="lineWidth">
        <number>0</number>
       </property>
       <property name="text">
        <string>4</string>
       </property>
       <property name="scaledContents">
        <bool>true</bool>
       </property>
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
      </widget>
     </item>
     <item row="3" column="0">
      <widget class="QLabel" name="Lane1_Time">
       <property name="font">
        <font>
         <pointsize>90</pointsize>
         <weight>75</weight>
         <bold>true</bold>
        </font>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgb(255, 255, 255)</string>
       </property>
       <property name="text">
        <string>4.5678</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
      </widget>
     </item>
     <item row="1" column="0">
      <widget class="QLabel" name="lblLane1">
       <property name="font">
        <font>
         <pointsize>36</pointsize>
         <weight>75</weight>
         <bold>true</bold>
        </font>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgb(255, 255, 255)</string>
       </property>
       <property name="text">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#e9e9e9;&quot;&gt;Lane 1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>619</width>
     <height>27</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionTest">
   <property name="text">
    <string>test</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

推荐答案

诸如while这类需要读取串行数据的True的阻塞任务不是GUI友好的,因此您不应该在相同的线程上运行,适当的选项是在另一个线程上执行它们,然后通过信号将必要的信息发送到主线程.

Blocking tasks such as the while True that you need to read the serial data are not GUI-friendly, so you should not run on the same thread, the appropriate option is to execute them on another thread, and send the necessary information to the main thread by signals.

import sys
import serial

from PyQt4 import QtCore, QtGui, uic

qtCreatorFile = "PinewoodDisplay.ui"

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

class SerialThread(QtCore.QThread):
    dataChanged = QtCore.pyqtSignal(str)
    def __init__(self, *args, **kwargs):
        QtCore.QThread.__init__(self, *args, **kwargs)
        self.ser = serial.Serial("/dev/ttyUSB1",115200)

    def run(self):
        while True:
            if self.ser.inWaiting()>0:
                inputValue = self.ser.readline().strip()
                self.dataChanged.emit(inputValue)

class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setupUi(self)
        thread = SerialThread(self)
        thread.dataChanged.connect(self.Lane1_Place.setText, QtCore.Qt.QueuedConnection)
        thread.start()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

使用QRunnableQThreadPool可以完成相同的任务,还可以发送可以使用QMetaObject::invokeMethod()

The same task could be done with QRunnable and QThreadPool, also to send the data you could use QMetaObject::invokeMethod()

这篇关于如何使用来自USB串行(来自Arduino)的数据刷新/更新QLabel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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