如何在PyQt5启动时自动读取串口数据并更新标签文本
实现PyQt5启动自动读取串口并更新标签文本
要实现程序启动后自动读取串口数据并更新标签,核心是避免阻塞UI线程,用Qt的多线程机制处理串口读取,通过信号槽更新UI。以下是具体实现步骤和代码:
步骤说明
- 安装依赖:先确保安装了
pyserial,执行命令:pip install pyserial - 分离UI与业务逻辑:Qt Designer生成的
Ui_Form类只负责界面布局,业务逻辑放在单独的窗口类中 - 用QThread处理串口读取:子线程循环读取串口数据,通过信号传递给主线程更新UI
- 程序启动自动启动线程,关闭窗口时释放资源
完整代码
from PyQt5 import QtCore, QtGui, QtWidgets import serial from serial.tools.list_ports import comports class SerialReaderThread(QtCore.QThread): # 定义信号,用于传递读取到的串口数据 data_received = QtCore.pyqtSignal(str) def __init__(self, port, baudrate=9600, parent=None): super().__init__(parent) self.port = port self.baudrate = baudrate self._is_running = True def run(self): try: # 打开串口 ser = serial.Serial(self.port, self.baudrate, timeout=1) while self._is_running: # 读取一行数据并解码 data = ser.readline().decode('utf-8').strip() if data: self.data_received.emit(data) ser.close() except Exception as e: self.data_received.emit(f"串口错误: {str(e)}") def stop(self): self._is_running = False self.wait() class MainWindow(QtWidgets.QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Form() self.ui.setupUi(self) # 替换为你的实际串口端口,比如Windows的COM3、Linux的/dev/ttyUSB0 # 可用comports()获取所有可用串口列表 self.serial_thread = SerialReaderThread(port='COM3') # 连接信号到更新标签的槽函数 self.serial_thread.data_received.connect(self.update_label) # 启动串口读取线程 self.serial_thread.start() def update_label(self, text): # 更新标签文本 self.ui.Title.setText(text) def closeEvent(self, event): # 窗口关闭时停止线程,释放资源 self.serial_thread.stop() event.accept() class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(666, 577) Form.setLayoutDirection(QtCore.Qt.LeftToRight) Form.setStyleSheet("background-color: rgb(0, 0, 0);\n" "color: #FFF;") self.formLayout = QtWidgets.QFormLayout(Form) self.formLayout.setObjectName("formLayout") self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") self.Title = QtWidgets.QLabel(Form) font = QtGui.QFont() font.setPointSize(60) self.Title.setFont(font) self.Title.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop) self.Title.setObjectName("Title") self.gridLayout.addWidget(self.Title, 3, 1, 1, 1) self.formLayout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.gridLayout) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "串口数据显示")) self.Title.setText(_translate("Form", "等待数据...")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
关键注意事项
- 串口端口配置:必须将代码中的
'COM3'替换为你实际使用的串口端口,可通过comports()函数获取系统中所有可用的串口列表。 - 线程安全:子线程绝对不能直接修改UI元素,必须通过信号槽机制将数据传递到主线程,由主线程更新UI,这是PyQt的线程安全要求。
- 资源释放:重写
closeEvent方法,在窗口关闭时停止串口线程并等待线程结束,避免程序退出时出现资源泄漏或异常。
内容的提问来源于stack exchange,提问作者Mahdi Sedighi Moghaddam
相关产品推荐
相关产品推荐

