一、成果展示
1、使用串口模拟工具形成两个相连接实际的串口(COM1、COM2)
2、运行程序,进入串口通信界面
3、打开串口
点击图片中红框部分,打开串口
通过串口模拟工具,可以发现串口已经打开:
4、在发送数据框中输入需要发送的数据,点击发送按钮:
5、从虚拟串口处可以看到串口COM1的数据已经发送,并且串口COM2由于已经打开,所以也接收到了数据,但由于数据没有读取,所以界面没有显示。
6、点击数据接收按钮,从CO2进行数据读取
二、具体开发步骤
1、UI界面设计
使用PyQT Desginer进行界面的设计,具体界面如下:
2、生成界面的python代码
使用PyUIC生成设计界面:
生成的Receive.py具体内容如下:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(892, 731)
self.formGroupBox = QtWidgets.QGroupBox(Form)
self.formGroupBox.setGeometry(QtCore.QRect(30, 80, 217, 231))
self.formGroupBox.setObjectName("formGroupBox")
self.formLayout = QtWidgets.QFormLayout(self.formGroupBox)
self.formLayout.setObjectName("formLayout")
self.s1__lb_8 = QtWidgets.QLabel(self.formGroupBox)
self.s1__lb_8.setObjectName("s1__lb_8")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.s1__lb_8)
self.sendName = QtWidgets.QComboBox(self.formGroupBox)
self.sendName.setObjectName("sendName")
self.sendName.addItem("")
self.sendName.addItem("")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.sendName)
self.s1__lb_14 = QtWidgets.QLabel(self.formGroupBox)
self.s1__lb_14.setObjectName("s1__lb_14")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.s1__lb_14)
self.sendBit = QtWidgets.QComboBox(self.formGroupBox)
self.sendBit.setObjectName("sendBit")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.sendBit.addItem("")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.sendBit)
self.s1__lb_10 = QtWidgets.QLabel(self.formGroupBox)
self.s1__lb_10.setObjectName("s1__lb_10")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.s1__lb_10)
self.s1__box_10 = QtWidgets.QComboBox(self.formGroupBox)
self.s1__box_10.setObjectName("s1__box_10")
self.s1__box_10.addItem("")
self.s1__box_10.addItem("")
self.s1__box_10.addItem("")
self.s1__box_10.addItem("")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.s1__box_10)
self.s1__lb_11 = QtWidgets.QLabel(self.formGroupBox)
self.s1__lb_11.setObjectName("s1__lb_11")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.s1__lb_11)
self.s1__box_11 = QtWidgets.QComboBox(self.formGroupBox)
self.s1__box_11.setObjectName("s1__box_11")
self.s1__box_11.addItem("")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.s1__box_11)
self.s1__lb_12 = QtWidgets.QLabel(self.formGroupBox)
self.s1__lb_12.setObjectName("s1__lb_12")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.s1__lb_12)
self.s1__box_12 = QtWidgets.QComboBox(self.formGroupBox)
self.s1__box_12.setObjectName("s1__box_12")
self.s1__box_12.addItem("")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.s1__box_12)
self.state_label_2 = QtWidgets.QLabel(self.formGroupBox)
self.state_label_2.setText("")
self.state_label_2.setObjectName("state_label_2")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.state_label_2)
self.openSend = QtWidgets.QPushButton(self.formGroupBox)
self.openSend.setObjectName("openSend")
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.openSend)
self.closeSend = QtWidgets.QPushButton(self.formGroupBox)
self.closeSend.setObjectName("closeSend")
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.closeSend)
self.sendData = QtWidgets.QTextEdit(Form)
self.sendData.setGeometry(QtCore.QRect(290, 110, 431, 221))
self.sendData.setObjectName("sendData")
self.groupBox = QtWidgets.QGroupBox(Form)
self.groupBox.setGeometry(QtCore.QRect(540, 40, 165, 67))
self.groupBox.setObjectName("groupBox")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
self.horizontalLayout.setObjectName("horizontalLayout")
self.startGenerate = QtWidgets.QPushButton(self.groupBox)
self.startGenerate.setObjectName("startGenerate")
self.horizontalLayout.addWidget(self.startGenerate)
self.stopGenerate = QtWidgets.QPushButton(self.groupBox)
self.stopGenerate.setObjectName("stopGenerate")
self.horizontalLayout.addWidget(self.stopGenerate)
self.formGroupBox_2 = QtWidgets.QGroupBox(Form)
self.formGroupBox_2.setGeometry(QtCore.QRect(30, 400, 221, 211))
self.formGroupBox_2.setObjectName("formGroupBox_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.formGroupBox_2)
self.gridLayout_2.setObjectName("gridLayout_2")
self.s1__box_25 = QtWidgets.QComboBox(self.formGroupBox_2)
self.s1__box_25.setObjectName("s1__box_25")
self.s1__box_25.addItem("")
self.gridLayout_2.addWidget(self.s1__box_25, 3, 2, 1, 2)
self.openReceive = QtWidgets.QPushButton(self.formGroupBox_2)
self.openReceive.setObjectName("openReceive")
self.gridLayout_2.addWidget(self.openReceive, 7, 1, 1, 2)
self.s1__lb_18 = QtWidgets.QLabel(self.formGroupBox_2)
self.s1__lb_18.setObjectName("s1__lb_18")
self.gridLayout_2.addWidget(self.s1__lb_18, 4, 1, 2, 1)
self.s1__box_22 = QtWidgets.QComboBox(self.formGroupBox_2)
self.s1__box_22.setObjectName("s1__box_22")
self.s1__box_22.addItem("")
self.s1__box_22.addItem("")
self.s1__box_22.addItem("")
self.s1__box_22.addItem("")
self.gridLayout_2.addWidget(self.s1__box_22, 2, 2, 1, 2)
self.s1__lb_21 = QtWidgets.QLabel(self.formGroupBox_2)
self.s1__lb_21.setObjectName("s1__lb_21")
self.gridLayout_2.addWidget(self.s1__lb_21, 3, 1, 1, 1)
self.s1__box_18 = QtWidgets.QComboBox(self.formGroupBox_2)
self.s1__box_18.setObjectName("s1__box_18")
self.s1__box_18.addItem("")
self.gridLayout_2.addWidget(self.s1__box_18, 4, 2, 2, 2)
self.state_label_3 = QtWidgets.QLabel(self.formGroupBox_2)
self.state_label_3.setText("")
self.state_label_3.setObjectName("state_label_3")
self.gridLayout_2.addWidget(self.state_label_3, 5, 0, 1, 1)
self.receiveName = QtWidgets.QComboBox(self.formGroupBox_2)
self.receiveName.setObjectName("receiveName")
self.receiveName.addItem("")
self.receiveName.addItem("")
self.gridLayout_2.addWidget(self.receiveName, 0, 2, 1, 2)
self.s1__lb_24 = QtWidgets.QLabel(self.formGroupBox_2)
self.s1__lb_24.setObjectName("s1__lb_24")
self.gridLayout_2.addWidget(self.s1__lb_24, 2, 1, 1, 1)
self.s1__lb_25 = QtWidgets.QLabel(self.formGroupBox_2)
self.s1__lb_25.setObjectName("s1__lb_25")
self.gridLayout_2.addWidget(self.s1__lb_25, 1, 1, 1, 1)
self.closeReceive = QtWidgets.QPushButton(self.formGroupBox_2)
self.closeReceive.setObjectName("closeReceive")
self.gridLayout_2.addWidget(self.closeReceive, 7, 3, 1, 1)
self.receiveBit = QtWidgets.QComboBox(self.formGroupBox_2)
self.receiveBit.setObjectName("receiveBit")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.receiveBit.addItem("")
self.gridLayout_2.addWidget(self.receiveBit, 1, 2, 1, 2)
self.s1__lb_23 = QtWidgets.QLabel(self.formGroupBox_2)
self.s1__lb_23.setObjectName("s1__lb_23")
self.gridLayout_2.addWidget(self.s1__lb_23, 0, 1, 1, 1)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(290, 40, 161, 41))
self.label.setObjectName("label")
self.startSend = QtWidgets.QPushButton(Form)
self.startSend.setGeometry(QtCore.QRect(760, 140, 93, 28))
self.startSend.setObjectName("startSend")
self.clearSend = QtWidgets.QPushButton(Form)
self.clearSend.setGeometry(QtCore.QRect(760, 220, 93, 28))
self.clearSend.setObjectName("clearSend")
self.line = QtWidgets.QFrame(Form)
self.line.setGeometry(QtCore.QRect(0, 350, 891, 20))
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.receiveData = QtWidgets.QTextEdit(Form)
self.receiveData.setGeometry(QtCore.QRect(290, 460, 431, 221))
self.receiveData.setObjectName("receiveData")
self.startReceive = QtWidgets.QPushButton(Form)
self.startReceive.setGeometry(QtCore.QRect(760, 490, 93, 28))
self.startReceive.setObjectName("startReceive")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(290, 390, 161, 41))
self.label_2.setObjectName("label_2")
self.clearReceive = QtWidgets.QPushButton(Form)
self.clearReceive.setGeometry(QtCore.QRect(760, 570, 93, 28))
self.clearReceive.setObjectName("clearReceive")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.formGroupBox.setTitle(_translate("Form", "串口设置"))
self.s1__lb_8.setText(_translate("Form", "发送串口:"))
self.sendName.setItemText(0, _translate("Form", "COM1"))
self.sendName.setItemText(1, _translate("Form", "COM2"))
self.s1__lb_14.setText(_translate("Form", "波特率:"))
self.sendBit.setItemText(0, _translate("Form", "115200"))
self.sendBit.setItemText(1, _translate("Form", "2400"))
self.sendBit.setItemText(2, _translate("Form", "4800"))
self.sendBit.setItemText(3, _translate("Form", "9600"))
self.sendBit.setItemText(4, _translate("Form", "14400"))
self.sendBit.setItemText(5, _translate("Form", "19200"))
self.sendBit.setItemText(6, _translate("Form", "38400"))
self.sendBit.setItemText(7, _translate("Form", "57600"))
self.sendBit.setItemText(8, _translate("Form", "76800"))
self.sendBit.setItemText(9, _translate("Form", "12800"))
self.sendBit.setItemText(10, _translate("Form", "230400"))
self.sendBit.setItemText(11, _translate("Form", "460800"))
self.s1__lb_10.setText(_translate("Form", "数据位:"))
self.s1__box_10.setItemText(0, _translate("Form", "8"))
self.s1__box_10.setItemText(1, _translate("Form", "7"))
self.s1__box_10.setItemText(2, _translate("Form", "6"))
self.s1__box_10.setItemText(3, _translate("Form", "5"))
self.s1__lb_11.setText(_translate("Form", "校验位:"))
self.s1__box_11.setItemText(0, _translate("Form", "N"))
self.s1__lb_12.setText(_translate("Form", "停止位:"))
self.s1__box_12.setItemText(0, _translate("Form", "1"))
self.openSend.setText(_translate("Form", "打开串口"))
self.closeSend.setText(_translate("Form", "关闭串口"))
self.groupBox.setTitle(_translate("Form", "发送数据自动生成"))
self.startGenerate.setText(_translate("Form", "开始"))
self.stopGenerate.setText(_translate("Form", "停止"))
self.formGroupBox_2.setTitle(_translate("Form", "串口设置"))
self.s1__box_25.setItemText(0, _translate("Form", "N"))
self.openReceive.setText(_translate("Form", "打开串口"))
self.s1__lb_18.setText(_translate("Form", "停止位:"))
self.s1__box_22.setItemText(0, _translate("Form", "8"))
self.s1__box_22.setItemText(1, _translate("Form", "7"))
self.s1__box_22.setItemText(2, _translate("Form", "6"))
self.s1__box_22.setItemText(3, _translate("Form", "5"))
self.s1__lb_21.setText(_translate("Form", "校验位:"))
self.s1__box_18.setItemText(0, _translate("Form", "1"))
self.receiveName.setItemText(0, _translate("Form", "COM1"))
self.receiveName.setItemText(1, _translate("Form", "COM2"))
self.s1__lb_24.setText(_translate("Form", "数据位:"))
self.s1__lb_25.setText(_translate("Form", "波特率:"))
self.closeReceive.setText(_translate("Form", "关闭串口"))
self.receiveBit.setItemText(0, _translate("Form", "115200"))
self.receiveBit.setItemText(1, _translate("Form", "2400"))
self.receiveBit.setItemText(2, _translate("Form", "4800"))
self.receiveBit.setItemText(3, _translate("Form", "9600"))
self.receiveBit.setItemText(4, _translate("Form", "14400"))
self.receiveBit.setItemText(5, _translate("Form", "19200"))
self.receiveBit.setItemText(6, _translate("Form", "38400"))
self.receiveBit.setItemText(7, _translate("Form", "57600"))
self.receiveBit.setItemText(8, _translate("Form", "76800"))
self.receiveBit.setItemText(9, _translate("Form", "12800"))
self.receiveBit.setItemText(10, _translate("Form", "230400"))
self.receiveBit.setItemText(11, _translate("Form", "460800"))
self.s1__lb_23.setText(_translate("Form", "接收串口:"))
self.label.setText(_translate("Form", "<html><head/><body><p><span style=\" font-size:20pt; font-weight:600;\">发送数据:</span></p></body></html>"))
self.startSend.setText(_translate("Form", "开始发送"))
self.clearSend.setText(_translate("Form", "清除"))
self.startReceive.setText(_translate("Form", "开始接收"))
self.label_2.setText(_translate("Form", "<html><head/><body><p><span style=\" font-size:20pt; font-weight:600;\">接收数据:</span></p></body></html>"))
self.clearReceive.setText(_translate("Form", "清除"))
3、新建python文件写按钮的功能,具体的System_receive.py代码见下:
import sys
from PyQt5 import QtWidgets
from Receive import Ui_Form
from PyQt5.QtCore import QTimer
import serial
import serial.tools.list_ports
def open_port(port, bps, timeout): # 打开串口
ret = False
try:
# 打开串口,并得到串口对象
ser = serial.Serial(port, bps, timeout=timeout)
# 判断是否打开成功
if ser.is_open:
ret = True
print(port + "打开了")
# threading.Thread(target=ReadData, args=(ser,)).start()
except Exception as e:
print("---异常---:", e)
return ret, ser
class Pyqt5_Serial(QtWidgets.QWidget, Ui_Form):
def __init__(self):
super(Pyqt5_Serial, self).__init__()
self.sendPort = None # 发送串口
self.sendCondition = False # 发送串口状态
self.receivePort = None # 接收串口
self.receiveCondition = False # 接收串口状态
self.setupUi(self)
self.init()
self.timer = QTimer(self) # 初始化一个定时器
self.setWindowTitle("Data_monitoring_System")
def generate(self):
head = '0xA1'
direction = "0x01"
distance = "0x10"
tail = "0xEE"
l = str(head) + str(direction) + str(distance) + str(tail)
self.sendData.append(l)
def init(self): # 把按钮等控件和函数对应起来
self.startGenerate.clicked.connect(self.generate_start) # 开始自动生成数据
self.stopGenerate.clicked.connect(self.generate_close) # 停止自动生成数据
self.openSend.clicked.connect(self.open_send_port) # 打开发送端口
self.closeSend.clicked.connect(self.close_send_port) # 关闭发送端口
self.openReceive.clicked.connect(self.open_receive_port) # 打开接收端口
self.closeReceive.clicked.connect(self.close_receive_port) # 关闭接收端口
self.startSend.clicked.connect(self.start_send) # 开始发送
self.clearSend.clicked.connect(self.clear_send) # 清空发送数据界面
self.startReceive.clicked.connect(self.start_receive) # 开始接收
self.clearReceive.clicked.connect(self.clear_receive) # 清空接收数据界面
def generate_start(self):
self.timer.start(1000) # 设置计时间隔并启动
self.timer.timeout.connect(self.generate)
def generate_close(self):
self.timer.stop()
def open_send_port(self): # 打开发送数据接口
port = self.sendName.currentText() # 发送接口的名字
bps = self.sendBit.currentText() # 发送接口的波特率
timeout = None # 发送接口的连接时间
self.sendCondition, self.sendPort = open_port(port, bps, timeout)
def open_receive_port(self): # 关闭发送接口
port = self.receiveName.currentText() # 接收接口的名字
bps = self.receiveBit.currentText() # 接受接口的波特率
timeout = None # 接收接口的连接时间
self.receiveCondition, self.receivePort = open_port(port, bps, timeout)
def close_send_port(self):
try:
# 判断是否打开成功
if self.sendPort.is_open:
self.sendPort.close()
self.sendCondition = False # 更新串口状态
except Exception as e:
print("---异常---:", e)
def close_receive_port(self): # 关闭数据接收端口
try:
# 判断是否打开成功
if self.receivePort.is_open:
self.receivePort.close() # 关闭数据接收端口
self.receiveCondition = False # 更新接收端口状态
except Exception as e:
print("---异常---:", e)
def start_send(self): # 开始发送
text = self.sendData.toPlainText() # 得到发送数据界面的当前发送数据
if self.sendCondition: # 如果发送数据端口打开
self.sendPort.write(text.encode("gbk")) # 写数据
def clear_send(self):
self.sendData.clear()
def start_receive(self):
if self.receiveCondition:
text = self.receivePort.read(self.receivePort.in_waiting).decode("gbk") # 从串口中读入数据
self.receiveData.append(text)
def clear_receive(self):
self.receiveData.clear()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) # 实例化一个应用对象
myshow = Pyqt5_Serial()
myshow.show() # 让控件在桌面上显示出来。控件在内存里创建,之后才能在显示器上显示出来。
sys.exit(app.exec_()) # 程序一直循环运行到主窗口被关闭
三、整个项目结构
Receive.py:自动生成的python源代码,用以生成ui的界面
Receive.ui:使用QT设计的ui界面
System_receive.py:界面功能程序,同时也是主程序