首页 > 解决方案 > 串行发送数据时 GUI 挂起

问题描述

我是 python 和 pyqt 的新手。我使用 qt 设计器创建了一个 gui。在那个 gui 中,当我单击按钮时,数据将串行发送。那时我的 Gui 挂在这里是我的代码

接口.py

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

# Form implementation generated from reading ui file 'status.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
from iF_UART import *

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig,
        _encoding)
except AttributeError:
    def _translate(context, text, disambig):
         return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow, data_queue):
        self.bt = UartDriver()
        self.bt.init('COM5', 115200, 0)
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(290, 140, 251, 91))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.action_func)
        self.radioButton = QtGui.QRadioButton(self.centralwidget)
        self.radioButton.setGeometry(QtCore.QRect(170, 180, 82, 17))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.data_queue = data_queue

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "PushButton", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))



    def action_func(self):
        send_len = self.bt.write("hai")

应用程序.py

from PyQt4 import QtGui,QtCore
import sys
import interface
from queue import Queue
from time import sleep


qt_app = None


class Simulator(QtGui.QMainWindow, interface.Ui_MainWindow):

    def __init__(self,data_queue):
        super(Simulator, self).__init__()
        self.setupUi(self, data_queue)
        self.data_queue = data_queue
        self.count = 0
        self.timer = QtCore.QTimer(self)
# Function Main Start
def main():
    global qt_app
    qt_app = QtGui.QApplication(sys.argv)
    data_queue = Queue()
    form = Simulator(data_queue)
    form.show()
    qt_app.exec_()


if __name__ == '__main__':
    main()

UART.py

import serial
import time
# time out 0.1 sec
TIME_OUT = 0.1
SER_MAX_DATA_SIZE = 1024

class UartDriver:
    def __init__(self):
        self.flow_control = None
        self.serial_handle = None
        self.handle = None

    def init(self, com_port, baud_rate, flow_con=False, handle = ''):
        self.flow_control = flow_con
        self.handle = handle
        print "Opening %s at %d" % (com_port, baud_rate)
        try:
            if(flow_con):
                self.serial_handle = serial.Serial(com_port, baud_rate, rtscts=True)
            else:
                self.serial_handle = serial.Serial(com_port, baud_rate, rtscts=False, timeout=TIME_OUT)
        except:
            print "Could not open port"
        finally:
            pass

    def write(self, s_data):
        w_len = None
        try:
            if (self.serial_handle):
                if(self.flow_control):
                    pass
                else:
                    print "Send ",  (s_data)
                    w_len = self.serial_handle.write(bytearray(s_data+"\n"))
                    print "test"
            else:
                print "Invalid handle"
        except:
            self.serial_handle.close()
        finally:
            return(w_len)

在 uart.py 写入发生。实际上写入没有完成,因为在语句写入后我只是打印一个单词测试,但它无法在控制台上打印。有人请帮我避免 gui 的挂起。

标签: pythonpython-2.7serial-portpyqt4

解决方案


我自己解决了这个问题。在我的 uart 类中,我以一定的波特率和固定的读取超时打开了一个串口。在我的串口打开中,我添加了一个额外的参数,即 write_timeout,它设置为零

self.serial_handle = serial.Serial(com_port, baud_rate, rtscts=False, timeout=TIME_OUT, write_timeout=0)

现在我的 GUI 工作正常。


推荐阅读