PyQt5 线程阻塞?

不痛不痒
  • 84

读取串口数据实时显示到textbrower,但会线程阻塞,求大神指教

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

# Form implementation generated from reading ui file '22.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
import sys, serial, pexpect, time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class BackendThread(QThread):
    sec_changed_signal = pyqtSignal(int)

    def __init__(self, sec=1000, parent=None):
        super().__init__(parent)
        self.sec = sec  # 默认1000ms

    def run(self):
        for i in range(self.sec):
            self.sec_changed_signal.emit(i)
            time.sleep(0.001)


class Ui_MainWindow:
    def setupUi(self, MainWindow):
        self.window = MainWindow
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(970, 575)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(300, 10, 641, 521))
        self.textBrowser.setMouseTracking(False)
        self.textBrowser.setObjectName("textBrowser")
        self.textBrowser.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.textBrowser.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 40, 281, 29))
        self.widget.setObjectName("widget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")

        # start com
        self.lineEdit = QtWidgets.QLineEdit(self.widget)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout.addWidget(self.lineEdit)
        self.pushButton = QtWidgets.QPushButton(self.widget)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)

        self.widget1 = QtWidgets.QWidget(self.centralwidget)
        self.widget1.setGeometry(QtCore.QRect(40, 440, 221, 51))
        self.widget1.setObjectName("widget1")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget1)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 20)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.pushButton_5 = QtWidgets.QPushButton(self.widget1)
        self.pushButton_5.setFlat(False)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout_3.addWidget(self.pushButton_5)
        self.pushButton_4 = QtWidgets.QPushButton(self.widget1)
        self.pushButton_4.setObjectName("pushButton_4")
        self.horizontalLayout_3.addWidget(self.pushButton_4)
        self.widget2 = QtWidgets.QWidget(self.centralwidget)
        self.widget2.setGeometry(QtCore.QRect(1, 123, 301, 271))
        self.widget2.setObjectName("widget2")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.widget2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.widget2)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.checkBox_6 = QtWidgets.QCheckBox(self.widget2)
        self.checkBox_6.setEnabled(True)
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.checkBox_6.setFont(font)
        self.checkBox_6.setAutoFillBackground(False)
        self.checkBox_6.setChecked(True)
        self.checkBox_6.setTristate(False)
        self.checkBox_6.setObjectName("checkBox_6")
        self.verticalLayout.addWidget(self.checkBox_6)
        self.checkBox_2 = QtWidgets.QCheckBox(self.widget2)
        self.checkBox_2.setObjectName("checkBox_2")
        self.verticalLayout.addWidget(self.checkBox_2)
        self.checkBox_5 = QtWidgets.QCheckBox(self.widget2)
        self.checkBox_5.setObjectName("checkBox_5")
        self.verticalLayout.addWidget(self.checkBox_5)
        self.checkBox_4 = QtWidgets.QCheckBox(self.widget2)
        self.checkBox_4.setObjectName("checkBox_4")
        self.verticalLayout.addWidget(self.checkBox_4)
        self.checkBox_3 = QtWidgets.QCheckBox(self.widget2)
        self.checkBox_3.setObjectName("checkBox_3")
        self.verticalLayout.addWidget(self.checkBox_3)
        self.checkBox = QtWidgets.QCheckBox(self.widget2)
        self.checkBox.setObjectName("checkBox")
        self.verticalLayout.addWidget(self.checkBox)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 970, 25))
        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)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

        self.lineEdit.setText(_translate("MainWindow", "请输入当前系统密码"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.lineEdit.selectAll()
        self.lineEdit.setFocus()
        self.pushButton.setText(_translate("MainWindow", "启动串口"))
        self.pushButton.clicked.connect(self.startCom)

        # 读取按钮和取消按钮功能连接
        # 启动线程
        thread = BackendThread()
        thread.sec_changed_signal.connect(self.update)
        self.pushButton_5.setText(_translate("MainWindow", "开始读取"))
        self.pushButton_5.clicked.connect(lambda: thread.start())
        self.pushButton_4.setText(_translate("MainWindow", "停止读取"))
        self.pushButton_4.clicked.connect(lambda : thread.terminate())

        self.label.setText(_translate("MainWindow", "选择串口位置:"))
        self.checkBox_6.setText(_translate("MainWindow", "All"))
        self.checkBox_2.setText(_translate("MainWindow", "Head"))
        self.checkBox_5.setText(_translate("MainWindow", "Wheel"))
        self.checkBox_4.setText(_translate("MainWindow", "Arm"))
        self.checkBox_3.setText(_translate("MainWindow", "Wheel"))
        self.checkBox.setText(_translate("MainWindow", "Query"))


    def startCom(self):
        pass_word = self.lineEdit.text()
        shell_cmd = 'cd /dev && sudo chmod 777 ttyUSB*'
        child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]).sendline(pass_word)

    @staticmethod
    def readData():
        pos = True
        with serial.Serial('/dev/ttyUSB0', '256000') as ser:
            with open("shoulder.txt", 'a') as f:
                while True:
                    s = ser.read()
                    h = hex(ord(s))
                    if h == '0xff' and pos:
                        f.write('\n')
                        f.write(time.strftime("%m-%d %H:%M:%S: ", time.localtime()))
                        f.write(h + " ")
                        pos = False
                    else:
                        f.write(
                            h + " "
                        )
                        pos = True

    def update(self, sec):
        self.readData()
        text_edit = QPlainTextEdit()
        text = open('shoulder.txt').read()
        self.textBrowser.setPlainText(text)

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

因为我要实时读取串口的数据存到一个文件,但将数据显示到textbrower时就会在readData()阻塞,不知道怎么办?

回复
阅读 2.6k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏