首页 > 解决方案 > PYQT 状态栏不更新

问题描述

我正在构建一个与 Arduino 通信的简单 QT UI。我实现了一个简单的设备自动检测机制。电脑正在寻找所有连接的串行设备并尝试向Hi!可用端口发送消息。如果 Arduino 连接到电脑,它会回复此消息。我想在 UI 的状态栏上显示设备搜索过程的状态。但是,状态栏不会更新。它只显示最新消息。最初的想法甚至没有用于设备搜索的按钮。我只是在调用findDevice()setupUi()但在这种情况下,UI 甚至直到findDevice()执行结束才开始。如果我在 UI 设置期间直接调用该方法,我会看到一个白色窗口,并且在findDevice()方法完成执行。那么为什么状态栏消息直到findDevice()执行结束才更新,我该如何消除pushButton_Connect?代码未完成。它有点长,但大部分是生成的代码。我只添加了几行。

编辑:这个问题的答案在这里:https ://stackoverflow.com/a/57500544/10370627 。另外我的closeEvent()方法在下面的代码中不起作用。对于这个问题,解决方案在这里:https ://stackoverflow.com/a/22460392/10370627

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file C:\ard_serial\python_code\calibrator_ui.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets
from pyqtgraph import PlotWidget
import numpy as np
import sys, time, serial, glob

# Global constants
ENCODING = "UTF-8"
GREETING = "Hi!"

DATA_READ = '0'
LIGHT_OFF = '1'
LED_ON = '2'
LASER_ON = '3'
EX_LED_ON = '4'
EX_LASER_ON = '5'

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # STARTS: User added class members
        self.ser_port = None
        # ENDS: User added class members
        
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1070, 595)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        MainWindow.setMinimumSize(QtCore.QSize(1070, 595))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.lineEdit_Input = QtWidgets.QLineEdit(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.lineEdit_Input.sizePolicy().hasHeightForWidth())
        self.lineEdit_Input.setSizePolicy(sizePolicy)
        self.lineEdit_Input.setObjectName("lineEdit_Input")
        self.gridLayout.addWidget(self.lineEdit_Input, 0, 1, 1, 1)
        self.graphicsView_PlotWidget = PlotWidget(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.graphicsView_PlotWidget.sizePolicy().hasHeightForWidth())
        self.graphicsView_PlotWidget.setSizePolicy(sizePolicy)
        self.graphicsView_PlotWidget.setMinimumSize(QtCore.QSize(1050, 490))
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.NoBrush)
        self.graphicsView_PlotWidget.setBackgroundBrush(QtGui.QColor('black'))
        self.graphicsView_PlotWidget.setObjectName("graphicsView_PlotWidget")
        self.gridLayout.addWidget(self.graphicsView_PlotWidget, 1, 0, 1, 5)
        self.label_Only_integers = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_Only_integers.sizePolicy().hasHeightForWidth())
        self.label_Only_integers.setSizePolicy(sizePolicy)
        self.label_Only_integers.setObjectName("label_Only_integers")
        self.gridLayout.addWidget(self.label_Only_integers, 0, 0, 1, 1)
        self.pushButton_Generate = QtWidgets.QPushButton(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_Generate.sizePolicy().hasHeightForWidth())
        self.pushButton_Generate.setSizePolicy(sizePolicy)
        self.pushButton_Generate.setObjectName("pushButton_Generate")
        self.gridLayout.addWidget(self.pushButton_Generate, 0, 2, 1, 1)
        self.pushButton_Connect = QtWidgets.QPushButton(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_Connect.sizePolicy().hasHeightForWidth())
        self.pushButton_Connect.setSizePolicy(sizePolicy)
        self.pushButton_Connect.setObjectName("pushButton_Connect")
        self.gridLayout.addWidget(self.pushButton_Connect, 0, 3, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1070, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
        # STARTS: User added setup code
        self.pushButton_Generate.clicked.connect(lambda:self.draw())
        '''
        I even do not want to use a push button for device search. But when I
        call findDevice() method the UI appears after the execution of
        findDevice() method.
        '''
        self.pushButton_Connect.clicked.connect(lambda:self.findDevice())
        
        x = np.random.normal(size = 500)
        y = np.random.normal(size = (3, 500))
        for i in range(3):
            self.graphicsView_PlotWidget.plot(x, y[i], pen = (i, 3)) 
            
        # ENDS: User added setup code
        
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Calibrator"))
        self.label_Only_integers.setText(_translate("MainWindow", "Only integers"))
        self.pushButton_Generate.setText(_translate("MainWindow", "Generate"))
        self.pushButton_Connect.setText(_translate("MainWindow", "Connect"))
        
    # STARTS: User added methods
    def findDevice(self):
        '''
        Here I expect to see all the status bar messages but I see only the last
        one. For instance if there is no serial device is connected, I only see
        <No serial device is connected> message on the status bar.
        '''
        self.statusbar.showMessage("Looking for device...")
        print("Looking for device...")
        
        if sys.platform.startswith('win'):
            ports = ['COM%s' % (i + 1) for i in range(256)]
        elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
            import subprocess
            # ports = glob.glob('/dev/tty[A-Za-z]*')
            ports = glob.glob('/dev/ttyUSB[0-9]*')
            for port in ports:
                process = subprocess.Popen(["sudo", "chmod", "777", port], stdout = subprocess.PIPE)
                output, error = process.communicate()
        else:
            raise EnvironmentError('Unsupported platform')
        
        for port in ports:
            try:
                self.ser_port = serial.Serial(port, 115200)
                time.sleep(1.8)
                self.statusbar.showMessage("Trying: " + str(port))
                print("Trying:", port)
                self.ser_port.write(GREETING.encode(ENCODING))
                time.sleep(0.1)
                self.ser_port.reset_input_buffer()
                time.sleep(1)
                read_data = self.ser_port.read_all().decode(ENCODING)
                if(GREETING == read_data):
                    self.statusbar.showMessage("Device detected on: " + str(port))
                    print("\nDevice detected on:", port)
                else:
                    self.statusbar.showMessage("No device detected")
                    print("No device detected")
            except (OSError, serial.SerialException):
                pass
            
        if(self.ser_port is None):
            print("No serial device is connected")
            self.statusbar.showMessage("No serial device is connected")
        
        
    def draw(self):
        self.graphicsView_PlotWidget.clear()
        
    def closeEvent(self, event):
        self.ledit.setText(LIGHT_OFF)
        if(self.ser_port is not None):
            ret_val = self.ser_port.close()
            print("Program terminated with return code: ", ret_val)
    # ENDS: User added methods

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

标签: python-3.xpyqtpyserial

解决方案


推荐阅读