所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 nixgnauhcuy's blog!
如需转载,请标明出处!
Life is short, you need Python. —— Bruce Eckel
前言
工作中偶尔会用到 python 来制作一些小工具,所以针对这些小工具,做了些简化,移除了一些比较复杂的功能,拿来分享。
UI 界面
在实现具体逻辑之前,我们要先设计好串口工具的 UI 界面,这里我直接使用的 Qt Designer 来设计串口界面的布局。
最终效果布置好布局后是这样的:
实际预览效果:
实现
打开 Qt Designer,点击新建 Main Window 窗体,
进入项目界面后,我们需要往里面拖入我们需要的控件,先添加两个 QGroupBox 控件并且设置文本为串口接收设置和串口发送设置, 一个作为我们的接收区,一个作为我们的发送区。
上面操作完成后,我们先来布置我们的接收区,先添加 Label 控件,分别设置文本为串口选择、波特率、停止位、数据位、校验位
的五个 Label 控件。
然后,我们要增加组合框,方便后面选择串口的参数,同样从左边拖出五个 Combo Box 控件,然后双击控件,这里我只拿波特率的组合框来描述,其他的例如停止位数据位还有校验位的操作是一样的,除了串口选择的组合框不用设置外,其他的都要设置。
双击波特率的组合框控件后,点击左下的 + 号,增加我们可选的波特率就可以了。
其他的 Combo Box 控件设置如下:
停止位分别设置 1、1.5、2 三个选项
数据位分别设置 8、7、6、5 四个选项
校验位分别设置 None、Odd、Even 三个选项
这样就把常用的波特率、停止位、数据位和校验位的选项框设置好了。
接下来,我们增加两个 RadioButton 和一个 Check Box 控件,分别设置两个 RadioButton 文本为 ASCII
和 HEX
,设置 Check Box 文本为时间戳
。
最后,增加两个 Push Button 控件还有一个 TextEdit 控件,Push Button 分别将文本命名为清除接收
和打开串口
。
这样基本上接收区就设置完毕了。
接下来是发送区,发送区中 Label、TextEdit、RadioButton、 Push Button 还有 Check Box 上面已经说过了,同样设置一下就可以了,这里就不占用太多篇幅了。
随后,我们要添加一个 LineEdit 控件,后面可以作为定时发送的时间。
这样,发送区也设置完毕了。
上面的接收区和发送区做完后,我们要将控件摆放整齐,并且设置控件的 objectName,方便后面编写程序调用控件时,一眼就知道编辑的是哪个控件。
控件的摆放我就不过多赘述了,无非就是调整位置和宽高,这里我标注一下我设置的控件 objectName,不然后面看代码的时候就不知道我是对哪个控件操作。
生成对应的 .py 文件
完成后,我们保存我们做好的 UI 到工程下,这里我将文件命名为 uart_tool_ui.ui 然后保存到后面要编写串口工具的工程目录下。保存的 .ui 文件还不能直接使用,要将它转为 .py 文件,方便后续调用,这里我使用的编译器是 vscode,使用 vscode 将 .ui 转为 .py 输出,vscode 要安装 pyqt 的扩展,这里我就不多说了,网上搜一下就可以了,我就直接贴上转化好的 .py 代码。
uart_tool_ui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'd:\test\my\python_uart_tool\uart_tool_ui.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 506)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(10, 10, 781, 291))
self.groupBox.setObjectName("groupBox")
self.timestamp_check_box = QtWidgets.QCheckBox(self.groupBox)
self.timestamp_check_box.setGeometry(QtCore.QRect(10, 225, 61, 16))
self.timestamp_check_box.setObjectName("timestamp_check_box")
self.label_7 = QtWidgets.QLabel(self.groupBox)
self.label_7.setGeometry(QtCore.QRect(10, 175, 54, 12))
self.label_7.setObjectName("label_7")
self.rec_hex_radio_button = QtWidgets.QRadioButton(self.groupBox)
self.rec_hex_radio_button.setGeometry(QtCore.QRect(70, 200, 41, 16))
self.rec_hex_radio_button.setObjectName("rec_hex_radio_button")
self.com_combo_box = QtWidgets.QComboBox(self.groupBox)
self.com_combo_box.setGeometry(QtCore.QRect(10, 50, 141, 22))
self.com_combo_box.setObjectName("com_combo_box")
self.stopbit_combo_box = QtWidgets.QComboBox(self.groupBox)
self.stopbit_combo_box.setGeometry(QtCore.QRect(58, 110, 91, 22))
self.stopbit_combo_box.setObjectName("stopbit_combo_box")
self.stopbit_combo_box.addItem("")
self.stopbit_combo_box.addItem("")
self.stopbit_combo_box.addItem("")
self.label_6 = QtWidgets.QLabel(self.groupBox)
self.label_6.setGeometry(QtCore.QRect(10, 145, 54, 12))
self.label_6.setObjectName("label_6")
self.baud_combo_box = QtWidgets.QComboBox(self.groupBox)
self.baud_combo_box.setGeometry(QtCore.QRect(58, 80, 91, 22))
self.baud_combo_box.setObjectName("baud_combo_box")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.baud_combo_box.addItem("")
self.label_5 = QtWidgets.QLabel(self.groupBox)
self.label_5.setGeometry(QtCore.QRect(10, 115, 54, 12))
self.label_5.setObjectName("label_5")
self.label_4 = QtWidgets.QLabel(self.groupBox)
self.label_4.setGeometry(QtCore.QRect(10, 85, 54, 12))
self.label_4.setObjectName("label_4")
self.checkbit_combo_box = QtWidgets.QComboBox(self.groupBox)
self.checkbit_combo_box.setGeometry(QtCore.QRect(58, 170, 91, 22))
self.checkbit_combo_box.setObjectName("checkbit_combo_box")
self.checkbit_combo_box.addItem("")
self.checkbit_combo_box.addItem("")
self.checkbit_combo_box.addItem("")
self.label_3 = QtWidgets.QLabel(self.groupBox)
self.label_3.setGeometry(QtCore.QRect(10, 22, 54, 20))
self.label_3.setObjectName("label_3")
self.databit_combo_box = QtWidgets.QComboBox(self.groupBox)
self.databit_combo_box.setGeometry(QtCore.QRect(58, 140, 91, 22))
self.databit_combo_box.setObjectName("databit_combo_box")
self.databit_combo_box.addItem("")
self.databit_combo_box.addItem("")
self.databit_combo_box.addItem("")
self.databit_combo_box.addItem("")
self.uart_en_push_button = QtWidgets.QPushButton(self.groupBox)
self.uart_en_push_button.setGeometry(QtCore.QRect(10, 250, 141, 23))
self.uart_en_push_button.setObjectName("uart_en_push_button")
self.rec_ascii_radio_button = QtWidgets.QRadioButton(self.groupBox)
self.rec_ascii_radio_button.setGeometry(QtCore.QRect(10, 200, 51, 16))
self.rec_ascii_radio_button.setObjectName("rec_ascii_radio_button")
self.uart_rec_show = QtWidgets.QTextEdit(self.groupBox)
self.uart_rec_show.setGeometry(QtCore.QRect(170, 10, 601, 271))
self.uart_rec_show.setFocusPolicy(QtCore.Qt.NoFocus)
self.uart_rec_show.setObjectName("uart_rec_show")
self.uart_clear_rec_push_button = QtWidgets.QPushButton(self.groupBox)
self.uart_clear_rec_push_button.setGeometry(QtCore.QRect(70, 220, 71, 23))
self.uart_clear_rec_push_button.setObjectName("uart_clear_rec_push_button")
self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_2.setGeometry(QtCore.QRect(10, 300, 781, 151))
self.groupBox_2.setObjectName("groupBox_2")
self.send_ascii_radio_button = QtWidgets.QRadioButton(self.groupBox_2)
self.send_ascii_radio_button.setGeometry(QtCore.QRect(10, 20, 51, 16))
self.send_ascii_radio_button.setObjectName("send_ascii_radio_button")
self.send_hex_radio_button = QtWidgets.QRadioButton(self.groupBox_2)
self.send_hex_radio_button.setGeometry(QtCore.QRect(70, 20, 41, 16))
self.send_hex_radio_button.setObjectName("send_hex_radio_button")
self.uart_timer_check_box = QtWidgets.QCheckBox(self.groupBox_2)
self.uart_timer_check_box.setGeometry(QtCore.QRect(10, 47, 47, 16))
self.uart_timer_check_box.setObjectName("uart_timer_check_box")
self.uart1_ms_label = QtWidgets.QLabel(self.groupBox_2)
self.uart1_ms_label.setGeometry(QtCore.QRect(140, 45, 20, 20))
self.uart1_ms_label.setObjectName("uart1_ms_label")
self.uart_timer_line_edit = QtWidgets.QLineEdit(self.groupBox_2)
self.uart_timer_line_edit.setGeometry(QtCore.QRect(70, 45, 61, 20))
self.uart_timer_line_edit.setObjectName("uart_timer_line_edit")
self.uart_send_push_button = QtWidgets.QPushButton(self.groupBox_2)
self.uart_send_push_button.setGeometry(QtCore.QRect(80, 70, 75, 23))
self.uart_send_push_button.setObjectName("uart_send_push_button")
self.uart_send_clear_push_button = QtWidgets.QPushButton(self.groupBox_2)
self.uart_send_clear_push_button.setGeometry(QtCore.QRect(0, 70, 75, 23))
self.uart_send_clear_push_button.setObjectName("uart_send_clear_push_button")
self.uart_send_show = QtWidgets.QTextEdit(self.groupBox_2)
self.uart_send_show.setGeometry(QtCore.QRect(170, 10, 601, 131))
self.uart_send_show.setFocusPolicy(QtCore.Qt.NoFocus)
self.uart_send_show.setObjectName("uart_send_show")
self.label = QtWidgets.QLabel(self.groupBox_2)
self.label.setGeometry(QtCore.QRect(10, 100, 18, 12))
self.label.setObjectName("label")
self.uart_tx_data_count_label = QtWidgets.QLabel(self.groupBox_2)
self.uart_tx_data_count_label.setGeometry(QtCore.QRect(30, 120, 100, 12))
self.uart_tx_data_count_label.setObjectName("uart_tx_data_count_label")
self.uart_rx_data_count_label = QtWidgets.QLabel(self.groupBox_2)
self.uart_rx_data_count_label.setGeometry(QtCore.QRect(30, 100, 100, 12))
self.uart_rx_data_count_label.setObjectName("uart_rx_data_count_label")
self.label_2 = QtWidgets.QLabel(self.groupBox_2)
self.label_2.setGeometry(QtCore.QRect(10, 120, 18, 12))
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menuBar.setObjectName("menuBar")
self.menu = QtWidgets.QMenu(self.menuBar)
self.menu.setObjectName("menu")
MainWindow.setMenuBar(self.menuBar)
self.actionguanyu = QtWidgets.QAction(MainWindow)
self.actionguanyu.setObjectName("actionguanyu")
self.menu.addAction(self.actionguanyu)
self.menuBar.addAction(self.menu.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.groupBox.setTitle(_translate("MainWindow", "串口接收设置"))
self.timestamp_check_box.setText(_translate("MainWindow", "时间戳"))
self.label_7.setText(_translate("MainWindow", "校验位"))
self.rec_hex_radio_button.setText(_translate("MainWindow", "HEX"))
self.stopbit_combo_box.setItemText(0, _translate("MainWindow", "1"))
self.stopbit_combo_box.setItemText(1, _translate("MainWindow", "1.5"))
self.stopbit_combo_box.setItemText(2, _translate("MainWindow", "2"))
self.label_6.setText(_translate("MainWindow", "数据位"))
self.baud_combo_box.setItemText(0, _translate("MainWindow", "110"))
self.baud_combo_box.setItemText(1, _translate("MainWindow", "300"))
self.baud_combo_box.setItemText(2, _translate("MainWindow", "600"))
self.baud_combo_box.setItemText(3, _translate("MainWindow", "1200"))
self.baud_combo_box.setItemText(4, _translate("MainWindow", "2400"))
self.baud_combo_box.setItemText(5, _translate("MainWindow", "4800"))
self.baud_combo_box.setItemText(6, _translate("MainWindow", "9600"))
self.baud_combo_box.setItemText(7, _translate("MainWindow", "14400"))
self.baud_combo_box.setItemText(8, _translate("MainWindow", "19200"))
self.baud_combo_box.setItemText(9, _translate("MainWindow", "38400"))
self.baud_combo_box.setItemText(10, _translate("MainWindow", "43000"))
self.baud_combo_box.setItemText(11, _translate("MainWindow", "57600"))
self.baud_combo_box.setItemText(12, _translate("MainWindow", "76800"))
self.baud_combo_box.setItemText(13, _translate("MainWindow", "115200"))
self.baud_combo_box.setItemText(14, _translate("MainWindow", "128000"))
self.baud_combo_box.setItemText(15, _translate("MainWindow", "230400"))
self.baud_combo_box.setItemText(16, _translate("MainWindow", "256000"))
self.baud_combo_box.setItemText(17, _translate("MainWindow", "460800"))
self.baud_combo_box.setItemText(18, _translate("MainWindow", "921600"))
self.baud_combo_box.setItemText(19, _translate("MainWindow", "1000000"))
self.baud_combo_box.setItemText(20, _translate("MainWindow", "2000000"))
self.baud_combo_box.setItemText(21, _translate("MainWindow", "3000000"))
self.label_5.setText(_translate("MainWindow", "停止位"))
self.label_4.setText(_translate("MainWindow", "波特率"))
self.checkbit_combo_box.setItemText(0, _translate("MainWindow", "None"))
self.checkbit_combo_box.setItemText(1, _translate("MainWindow", "Odd"))
self.checkbit_combo_box.setItemText(2, _translate("MainWindow", "Even"))
self.label_3.setText(_translate("MainWindow", "串口选择"))
self.databit_combo_box.setItemText(0, _translate("MainWindow", "8"))
self.databit_combo_box.setItemText(1, _translate("MainWindow", "7"))
self.databit_combo_box.setItemText(2, _translate("MainWindow", "6"))
self.databit_combo_box.setItemText(3, _translate("MainWindow", "5"))
self.uart_en_push_button.setText(_translate("MainWindow", "打开串口"))
self.rec_ascii_radio_button.setText(_translate("MainWindow", "ASCII"))
self.uart_clear_rec_push_button.setText(_translate("MainWindow", "清除接收"))
self.groupBox_2.setTitle(_translate("MainWindow", "串口发送设置"))
self.send_ascii_radio_button.setText(_translate("MainWindow", "ASCII"))
self.send_hex_radio_button.setText(_translate("MainWindow", "HEX"))
self.uart_timer_check_box.setText(_translate("MainWindow", "定时"))
self.uart1_ms_label.setText(_translate("MainWindow", "ms"))
self.uart_send_push_button.setText(_translate("MainWindow", "发送数据"))
self.uart_send_clear_push_button.setText(_translate("MainWindow", "清除发送"))
self.label.setText(_translate("MainWindow", "R:"))
self.uart_tx_data_count_label.setText(_translate("MainWindow", "0"))
self.uart_rx_data_count_label.setText(_translate("MainWindow", "0"))
self.label_2.setText(_translate("MainWindow", "T:"))
self.menu.setTitle(_translate("MainWindow", "帮助"))
self.actionguanyu.setText(_translate("MainWindow", "关于"))
查看效果
在工程中编写我们的 main.py,运行看看效果,
main.py 代码如下
import os
import sys
from Ui_uart_tool_ui import Ui_MainWindow
from PyQt5.QtWidgets import (QApplication, QMainWindow)
class MyPyQT_Form(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
my_pyqt_form = MyPyQT_Form()
my_pyqt_form.show()
sys.exit(app.exec_())
然后运行效果如下:
结语
python 串口逻辑代码的编写,得留到下一篇了,平时工作忙不是特别有空,等我空闲的时候再补上!我本身不是学 python 的,所以难免会有出错或者你认为代码不合理的地方,这些也希望多多谅解和指教,我会及时修改的!
关于本篇的相关代码我也上传到 github 和 csdn 上去了,有兴趣的可以访问 github 或 csdn 查看,后面的代码也会在这个仓库中补充,不介意也可以点个 star。