forked from PyQt5/PyQt
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SerialDebugAssistant.py
147 lines (131 loc) · 5.41 KB
/
SerialDebugAssistant.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年11月6日
@author: Irony
@site: https://pyqt5.com , https://github.com/892768447
@email: [email protected]
@file: SerialDebugAssistant
@description: 串口调试小助手
"""
from PyQt5.QtCore import pyqtSlot, QIODevice, QByteArray
from PyQt5.QtSerialPort import QSerialPortInfo, QSerialPort
from PyQt5.QtWidgets import QWidget, QMessageBox
from Lib.UiSerialPort import Ui_FormSerialPort # @UnresolvedImport
__Author__ = """By: Irony
QQ: 892768447
Email: [email protected]"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class Window(QWidget, Ui_FormSerialPort):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.setupUi(self)
self._serial = QSerialPort(self) # 用于连接串口的对象
self._serial.readyRead.connect(self.onReadyRead) # 绑定数据读取信号
# 首先获取可用的串口列表
self.getAvailablePorts()
@pyqtSlot()
def on_buttonConnect_clicked(self):
# 打开或关闭串口按钮
if self._serial.isOpen():
# 如果串口是打开状态则关闭
self._serial.close()
self.textBrowser.append('串口已关闭')
self.buttonConnect.setText('打开串口')
self.labelStatus.setProperty('isOn', False)
self.labelStatus.style().polish(self.labelStatus) # 刷新样式
return
# 根据配置连接串口
name = self.comboBoxPort.currentText()
if not name:
QMessageBox.critical(self, '错误', '没有选择串口')
return
port = self._ports[name]
# self._serial.setPort(port)
# 根据名字设置串口(也可以用上面的函数)
self._serial.setPortName(port.systemLocation())
# 设置波特率
self._serial.setBaudRate( # 动态获取,类似QSerialPort::Baud9600这样的吧
getattr(QSerialPort, 'Baud' + self.comboBoxBaud.currentText()))
# 设置校验位
self._serial.setParity( # QSerialPort::NoParity
getattr(QSerialPort, self.comboBoxParity.currentText() + 'Parity'))
# 设置数据位
self._serial.setDataBits( # QSerialPort::Data8
getattr(QSerialPort, 'Data' + self.comboBoxData.currentText()))
# 设置停止位
self._serial.setStopBits( # QSerialPort::Data8
getattr(QSerialPort, self.comboBoxStop.currentText()))
# NoFlowControl 没有流程控制
# HardwareControl 硬件流程控制(RTS/CTS)
# SoftwareControl 软件流程控制(XON/XOFF)
# UnknownFlowControl 未知控制
self._serial.setFlowControl(QSerialPort.NoFlowControl)
# 读写方式打开串口
ok = self._serial.open(QIODevice.ReadWrite)
if ok:
self.textBrowser.append('打开串口成功')
self.buttonConnect.setText('关闭串口')
self.labelStatus.setProperty('isOn', True)
self.labelStatus.style().polish(self.labelStatus) # 刷新样式
else:
self.textBrowser.append('打开串口失败')
self.buttonConnect.setText('打开串口')
self.labelStatus.setProperty('isOn', False)
self.labelStatus.style().polish(self.labelStatus) # 刷新样式
@pyqtSlot()
def on_buttonSend_clicked(self):
# 发送消息按钮
if not self._serial.isOpen():
print('串口未连接')
return
text = self.plainTextEdit.toPlainText()
if not text:
return
text = QByteArray(text.encode('gb2312')) # emmm windows 测试的工具貌似是这个编码
if self.checkBoxHexSend.isChecked():
# 如果勾选了hex发送
text = text.toHex()
# 发送数据
print('发送数据:', text)
self._serial.write(text)
def onReadyRead(self):
# 数据接收响应
if self._serial.bytesAvailable():
# 当数据可读取时
# 这里只是简答测试少量数据,如果数据量太多了此处readAll其实并没有读完
# 需要自行设置粘包协议
data = self._serial.readAll()
if self.checkBoxHexView.isChecked():
# 如果勾选了hex显示
data = data.toHex()
data = data.data()
# 解码显示(中文啥的)
try:
self.textBrowser.append('我收到了: ' + data.decode('gb2312'))
except:
# 解码失败
self.textBrowser.append('我收到了: ' + repr(data))
def getAvailablePorts(self):
# 获取可用的串口
self._ports = {} # 用于保存串口的信息
infos = QSerialPortInfo.availablePorts()
infos.reverse() # 逆序
for info in infos:
# 通过串口名字-->关联串口变量
self._ports[info.portName()] = info
self.comboBoxPort.addItem(info.portName())
def closeEvent(self, event):
if self._serial.isOpen():
self._serial.close()
super(Window, self).closeEvent(event)
if __name__ == '__main__':
import sys
import cgitb
sys.excepthook = cgitb.enable(1, None, 5, '')
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())