所有文章除特別聲明外振愿,均采用 CC BY-NC-SA 4.0 許可協(xié)議。轉載請注明來自 nixgnauhcuy's blog弛饭!
如需轉載冕末,請標明出處!
Life is short, you need Python. —— Bruce Eckel
前言
工作中偶爾會用到 python 來制作一些小工具侣颂,所以針對這些小工具档桃,做了些簡化,移除了一些比較復雜的功能憔晒,拿來分享藻肄。
UI 界面
在實現(xiàn)具體邏輯之前,我們要先設計好串口工具的 UI 界面拒担,這里我直接使用的 Qt Designer 來設計串口界面的布局嘹屯。
最終效果布置好布局后是這樣的:
實際預覽效果:
實現(xiàn)
打開 Qt Designer,點擊新建 Main Window 窗體从撼,
進入項目界面后州弟,我們需要往里面拖入我們需要的控件,先添加兩個 QGroupBox 控件并且設置文本為串口接收設置和串口發(fā)送設置低零, 一個作為我們的接收區(qū)婆翔,一個作為我們的發(fā)送區(qū)。
上面操作完成后掏婶,我們先來布置我們的接收區(qū)浙滤,先添加 Label 控件,分別設置文本為串口選擇气堕、波特率、停止位畔咧、數(shù)據(jù)位茎芭、校驗位
的五個 Label 控件。
然后誓沸,我們要增加組合框梅桩,方便后面選擇串口的參數(shù),同樣從左邊拖出五個 Combo Box 控件拜隧,然后雙擊控件宿百,這里我只拿波特率的組合框來描述趁仙,其他的例如停止位數(shù)據(jù)位還有校驗位的操作是一樣的,除了串口選擇的組合框不用設置外垦页,其他的都要設置雀费。
雙擊波特率的組合框控件后,點擊左下的 + 號痊焊,增加我們可選的波特率就可以了盏袄。
其他的 Combo Box 控件設置如下:
停止位分別設置 1、1.5薄啥、2 三個選項
數(shù)據(jù)位分別設置 8辕羽、7、6垄惧、5 四個選項
校驗位分別設置 None刁愿、Odd、Even 三個選項
這樣就把常用的波特率到逊、停止位铣口、數(shù)據(jù)位和校驗位的選項框設置好了。
接下來蕾管,我們增加兩個 RadioButton 和一個 Check Box 控件枷踏,分別設置兩個 RadioButton 文本為 ASCII
和 HEX
,設置 Check Box 文本為時間戳
掰曾。
最后旭蠕,增加兩個 Push Button 控件還有一個 TextEdit 控件,Push Button 分別將文本命名為清除接收
和打開串口
旷坦。
這樣基本上接收區(qū)就設置完畢了掏熬。
接下來是發(fā)送區(qū),發(fā)送區(qū)中 Label秒梅、TextEdit旗芬、RadioButton、 Push Button 還有 Check Box 上面已經(jīng)說過了捆蜀,同樣設置一下就可以了疮丛,這里就不占用太多篇幅了。
隨后辆它,我們要添加一個 LineEdit 控件誊薄,后面可以作為定時發(fā)送的時間。
這樣锰茉,發(fā)送區(qū)也設置完畢了呢蔫。
上面的接收區(qū)和發(fā)送區(qū)做完后,我們要將控件擺放整齊飒筑,并且設置控件的 objectName片吊,方便后面編寫程序調(diào)用控件時绽昏,一眼就知道編輯的是哪個控件。
控件的擺放我就不過多贅述了俏脊,無非就是調(diào)整位置和寬高全谤,這里我標注一下我設置的控件 objectName,不然后面看代碼的時候就不知道我是對哪個控件操作联予。
生成對應的 .py 文件
完成后啼县,我們保存我們做好的 UI 到工程下,這里我將文件命名為 uart_tool_ui.ui 然后保存到后面要編寫串口工具的工程目錄下沸久。保存的 .ui 文件還不能直接使用季眷,要將它轉為 .py 文件,方便后續(xù)調(diào)用卷胯,這里我使用的編譯器是 vscode子刮,使用 vscode 將 .ui 轉為 .py 輸出,vscode 要安裝 pyqt 的擴展窑睁,這里我就不多說了挺峡,網(wǎng)上搜一下就可以了,我就直接貼上轉化好的 .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", "數(shù)據(jù)位"))
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", "串口發(fā)送設置"))
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", "發(fā)送數(shù)據(jù)"))
self.uart_send_clear_push_button.setText(_translate("MainWindow", "清除發(fā)送"))
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。