Python Qt GUI设计:做一款串口调试助手(实战篇—1)

目录

1、UI设计

2、将UI文件转换为Py文件

3、逻辑功能实现

3.1、初始化程序

3.2、串口检测程序

3.3、 设置及打开串口程序

3.4、定时发送数据程序

3.5、发送数据程序

3.6、接收数据程序

3.7、保存日志程序

3.8、加载日志程序

3.9、打开博客、公众号程序

3.10、清除发送和接收数据显示程序

3.11、关闭串口程序


Python Qt GUI设计系列博文终于到了实战篇,本篇博文将贯穿之前的基础知识点实现一款串口调试助手。

关注【公众号】 美男子玩编程,回复关键字:串口调试助手,获取项目源码~

资源下载:PythonQt串口调试助手-嵌入式文档类资源-CSDN下载

1、UI设计

UI设计使用Qt Creator实现,组件布局如下所示:

2、将UI文件转换为Py文件

这里使用Python脚本的方式将UI文件转换为Python文件,代码如下所示:

import os
import os.pathdir ='./' #文件所在的路径#找出路径下所有的.ui文件
def listUiFile():list = []files = os.listdir(dir)for filename in files:#print(filename)if os.path.splitext(filename)[1] == '.ui':list.append(filename)return list#把扩展名未.ui的转换成.py的文件
def transPyFile(filename):return os.path.splitext(filename)[0] + '.py'#通过命令把.ui文件转换成.py文件
def runMain():list = listUiFile()for uifile in list:pyfile = transPyFile(uifile)cmd = 'pyuic5 -o {pyfile} {uifile}'.format(pyfile=pyfile, uifile=uifile)os.system(cmd)if __name__ =="__main__":runMain()

3、逻辑功能实现

3.1、初始化程序

首先初始化一些组件和标志位的状态,设置信号与槽的关系,实现代码如下所示:

    # 初始化程序def __init__(self):super(Pyqt5_Serial, self).__init__()self.setupUi(self)self.init()self.ser = serial.Serial()self.port_check()# 设置Logo和标题self.setWindowIcon(QIcon('Com.png'))self.setWindowTitle("串口调试助手 【公众号】美男子玩编程")# 设置禁止拉伸窗口大小self.setFixedSize(self.width(), self.height())# 发送数据和接收数据数目置零self.data_num_sended = 0self.Lineedit2.setText(str(self.data_num_sended))self.data_num_received = 0self.Lineedit3.setText(str(self.data_num_received))# 串口关闭按钮使能关闭self.Pushbuttom3.setEnabled(False)# 发送框、文本框清除self.Text1.setText("")self.Text2.setText("")# 建立控件信号与槽关系def init(self):# 串口检测按钮self.Pushbuttom2.clicked.connect(self.port_check)# 串口打开按钮self.Pushbuttom1.clicked.connect(self.port_open)# 串口关闭按钮self.Pushbuttom3.clicked.connect(self.port_close)# 定时发送数据self.timer_send = QTimer()self.timer_send.timeout.connect(self.data_send)self.Checkbox7.stateChanged.connect(self.data_send_timer)# 发送数据按钮self.Pushbuttom6.clicked.connect(self.data_send)# 加载日志self.Pushbuttom4.clicked.connect(self.savefiles)# 加载日志self.Pushbuttom5.clicked.connect(self.openfiles)# 跳转链接self.commandLinkButton1.clicked.connect(self.link)# 清除发送按钮self.Pushbuttom7.clicked.connect(self.send_data_clear)# 清除接收按钮self.Pushbuttom8.clicked.connect(self.receive_data_clear)

3.2、串口检测程序

检测电脑上所有串口,实现代码如下所示:

    # 串口检测def port_check(self):# 检测所有存在的串口,将信息存储在字典中self.Com_Dict = {}port_list = list(serial.tools.list_ports.comports())self.Combobox1.clear()for port in port_list:self.Com_Dict["%s" % port[0]] = "%s" % port[1]self.Combobox1.addItem(port[0])# 无串口判断if len(self.Com_Dict) == 0:self.Combobox1.addItem("无串口")

3.3、 设置及打开串口程序

检测到串口后进行配置,打开串口,并且启动定时器一直接收用户输入,实现代码如下所示:

    # 打开串口def port_open(self):self.ser.port        = self.Combobox1.currentText()      # 串口号self.ser.baudrate    = int(self.Combobox2.currentText()) # 波特率flag_data = int(self.Combobox3.currentText())  # 数据位if flag_data == 5:self.ser.bytesize = serial.FIVEBITSelif flag_data == 6:self.ser.bytesize = serial.SIXBITSelif flag_data == 7:self.ser.bytesize = serial.SEVENBITSelse:self.ser.bytesize = serial.EIGHTBITSflag_data = self.Combobox4.currentText()  # 校验位if flag_data == "None":self.ser.parity = serial.PARITY_NONEelif flag_data == "Odd":self.ser.parity = serial.PARITY_ODDelse:self.ser.parity = serial.PARITY_EVENflag_data = int(self.Combobox5.currentText()) # 停止位if flag_data == 1:self.ser.stopbits = serial.STOPBITS_ONEelse:self.ser.stopbits = serial.STOPBITS_TWOflag_data = self.Combobox6.currentText()  # 流控if flag_data == "No Ctrl Flow":self.ser.xonxoff = False  #软件流控self.ser.dsrdtr  = False  #硬件流控 DTRself.ser.rtscts  = False  #硬件流控 RTSelif flag_data == "SW Ctrl Flow":self.ser.xonxoff = True  #软件流控else:         if self.Checkbox3.isChecked():self.ser.dsrdtr = True  #硬件流控 DTRif self.Checkbox4.isChecked():self.ser.rtscts = True  #硬件流控 RTStry:time.sleep(0.1)self.ser.open()except:QMessageBox.critical(self, "串口异常", "此串口不能被打开!")return None# 串口打开后,切换开关串口按钮使能状态,防止失误操作        if self.ser.isOpen():self.Pushbuttom1.setEnabled(False)self.Pushbuttom3.setEnabled(True)self.formGroupBox1.setTitle("串口状态(开启)")# 定时器接收数据self.timer = QTimer()self.timer.timeout.connect(self.data_receive)# 打开串口接收定时器,周期为1msself.timer.start(1)

3.4、定时发送数据程序

通过定时器,可支持1ms至30s之间数据定时,实现代码如下所示:

    # 定时发送数据def data_send_timer(self):try:if 1<= int(self.Lineedit1.text()) <= 30000:  # 定时时间1ms~30s内if self.Checkbox7.isChecked():self.timer_send.start(int(self.Lineedit1.text()))self.Lineedit1.setEnabled(False)else:self.timer_send.stop()self.Lineedit1.setEnabled(True)else:QMessageBox.critical(self, '定时发送数据异常', '定时发送数据周期仅可设置在30秒内!')except:QMessageBox.critical(self, '定时发送数据异常', '请设置正确的数值类型!')

3.5、发送数据程序

可以发送ASCII字符和十六进制类型数据,并且可以在数据前显示发送的时间,在数据后进行换行,发送一个字节,TX标志会自动累加,实现代码如下所示:

    # 发送数据def data_send(self):if self.ser.isOpen():input_s = self.Text2.toPlainText()# 判断是否为非空字符串if input_s != "":# 时间显示if self.Checkbox5.isChecked():self.Text1.insertPlainText((time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " ")# HEX发送if self.Checkbox1.isChecked():  input_s = input_s.strip()send_list = []while input_s != '':try:num = int(input_s[0:2], 16)except ValueError:QMessageBox.critical(self, '串口异常', '请输入规范十六进制数据,以空格分开!')return Noneinput_s = input_s[2:].strip()send_list.append(num)input_s = bytes(send_list)# ASCII发送else:  input_s = (input_s).encode('utf-8')# HEX接收显示if self.Checkbox2.isChecked():  out_s = ''for i in range(0, len(input_s)):out_s = out_s + '{:02X}'.format(input_s[i]) + ' 'self.Text1.insertPlainText(out_s)# ASCII接收显示else:  self.Text1.insertPlainText(input_s.decode('utf-8')) # 接收换行              if self.Checkbox6.isChecked():self.Text1.insertPlainText('\r\n')# 获取到Text光标textCursor = self.Text1.textCursor()# 滚动到底部textCursor.movePosition(textCursor.End)# 设置光标到Text中去self.Text1.setTextCursor(textCursor)# 统计发送字符数量num = self.ser.write(input_s)self.data_num_sended += numself.Lineedit2.setText(str(self.data_num_sended))else:pass

3.6、接收数据程序

可以接收ASCII字符和十六进制类型数据,并且可以在数据前显示发送的时间,在数据后进行换行,接收一个字节,RX标志会自动累加,实现代码如下所示:

    # 接收数据def data_receive(self):try:num = self.ser.inWaiting()if num > 0:time.sleep(0.1)num = self.ser.inWaiting()  #延时,再读一次数据,确保数据完整性except:QMessageBox.critical(self, '串口异常', '串口接收数据异常,请重新连接设备!')self.port_close()return Noneif num > 0:data = self.ser.read(num)num = len(data)# 时间显示if self.Checkbox5.isChecked():self.Text1.insertPlainText((time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + " ")# HEX显示数据if self.Checkbox2.checkState():out_s = ''for i in range(0, len(data)):out_s = out_s + '{:02X}'.format(data[i]) + ' 'self.Text1.insertPlainText(out_s)# ASCII显示数据else:self.Text1.insertPlainText(data.decode('utf-8'))# 接收换行              if self.Checkbox6.isChecked():self.Text1.insertPlainText('\r\n')# 获取到text光标textCursor = self.Text1.textCursor()# 滚动到底部textCursor.movePosition(textCursor.End)# 设置光标到text中去self.Text1.setTextCursor(textCursor)# 统计接收字符的数量self.data_num_received += numself.Lineedit3.setText(str(self.data_num_received))else:pass

3.7、保存日志程序

将接收框中收发的数据保存到TXT文本中,实现代码如下所示:

    # 保存日志def savefiles(self):dlg = QFileDialog()filenames = dlg.getSaveFileName(None, "保存日志文件", None, "Txt files(*.txt)")try:with open(file = filenames[0], mode='w', encoding='utf-8') as file:file.write(self.Text1.toPlainText())except:QMessageBox.critical(self, '日志异常', '保存日志文件失败!')

3.8、加载日志程序

加载保存到TXT文本中的数据信息到发送框中,实现代码如下所示:

    # 加载日志def openfiles(self):dlg = QFileDialog()filenames = dlg.getOpenFileName(None, "加载日志文件", None, "Txt files(*.txt)")try:with open(file = filenames[0], mode='r', encoding='utf-8') as file:self.Text2.setPlainText(file.read())except:QMessageBox.critical(self, '日志异常', '加载日志文件失败!')

3.9、打开博客、公众号程序

点击按钮,打开我的公众号二维码和博客主页,实现代码如下所示:

    # 打开博客链接和公众号二维码def link(self):dialog = QDialog()label_img = QLabel()label_img.setAlignment(Qt.AlignCenter)    label_img.setPixmap(QPixmap("./img.jpg"))vbox = QVBoxLayout()vbox.addWidget(label_img)dialog.setLayout(vbox)dialog.setWindowTitle("快扫码关注公众号吧~")dialog.setWindowModality(Qt.ApplicationModal)dialog.exec_()webbrowser.open('https://blog.csdn.net/m0_38106923')

3.10、清除发送和接收数据显示程序

清除发送数据框和接收数据框的内容和计数次数,实现代码如下所示:

    # 清除发送数据显示def send_data_clear(self):self.Text2.setText("")self.data_num_sended = 0self.Lineedit2.setText(str(self.data_num_sended))# 清除接收数据显示def receive_data_clear(self):self.Text1.setText("")self.data_num_received = 0self.Lineedit3.setText(str(self.data_num_received))

3.11、关闭串口程序

关闭串口,停止定时器,重置组件和标志状态,实现代码如下所示:

    # 关闭串口def port_close(self):try:self.timer.stop()self.timer_send.stop()self.ser.close()except:QMessageBox.critical(self, '串口异常', '关闭串口失败,请重启程序!')return None# 切换开关串口按钮使能状态和定时发送使能状态self.Pushbuttom1.setEnabled(True)self.Pushbuttom3.setEnabled(False)self.Lineedit1.setEnabled(True)# 发送数据和接收数据数目置零self.data_num_sended = 0self.Lineedit2.setText(str(self.data_num_sended))self.data_num_received = 0self.Lineedit3.setText(str(self.data_num_received))self.formGroupBox1.setTitle("串口状态(关闭)")

资源下载:PythonQt串口调试助手-嵌入式文档类资源-CSDN下载 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/354317.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Linux - 第23节 - Linux高级IO(一)

目录 1.IO的基本概念 2.钓鱼五人组 3.五种IO模型 3.1.阻塞IO 3.2.非阻塞IO 3.3.信号驱动IO 3.4.IO多路转接 3.5.异步IO 4.高级IO重要概念 4.1.同步通信 VS 异步通信 4.2.阻塞 VS 非阻塞 5.其他高级IO 6.阻塞IO 7.非阻塞IO 7.1.fcntl函数介绍 7.2.fcntl函数的使…

Mac上iPad Pro高清桌面动态壁纸

ipad pro壁纸哪里下&#xff1f;Mac上iPad Pro高清桌面动态壁纸带给大家&#xff0c;iPad壁纸拥有多种色彩样式变幻。有了这款壁纸将会让您苹果电脑桌面可以与众不同。

iPhone 系列壁纸,太好看了!

以下内容来自公众号逆锋起笔&#xff0c;关注回复壁纸获取更多 &#xfe61;图源网络&#xff0c;如侵联删 36 张图带你理解计算机网络 6 大基础知识点 一个疫情催生的有趣开源项目 Win11 全新壁纸下载 苹果 iPhone 13 内置原生壁纸下载 macOS 12 内置原生壁纸下载 17 张程序员…

苹果macOS 13 Ventura 5K原生动态壁纸

WWDC22苹果开发者大会上&#xff0c;推出了macOS 13&#xff0c;代号Ventura&#xff08;文图拉)&#xff0c;让 Mac 体验更胜以往。Ventura的原生动态壁纸延续上一代的简约流线型设计&#xff0c;以橙色到红色的过渡为主体&#xff0c;天蓝到蓝黑色的过渡为背景&#xff0c;依…

苹果iPad OS 16原生壁纸Mac动态桌面

WWDC22苹果开发者大会上&#xff0c;除了推出macOS 13&#xff0c;还有OS 16系统&#xff0c;相比macOS 13内置壁纸&#xff0c;同样的简约流线设计&#xff0c;苹果iPad OS 16原生壁纸更显得具有科技感&#xff0c;制作成Mac动态桌面壁纸&#xff0c;也是让人眼前一亮。 苹果i…

唯美云朵壁纸苹果动态

再怎么 葱郁 宽广的森林 &#xff0c;也留不住 随性 自在的云 &#xff01;为您带来唯美云朵壁纸苹果动态&#xff0c;让桌面更有韵味吧&#xff01; 唯美云朵壁纸苹果动态

壁纸|苹果Live壁纸以及静态壁纸,给大家分享点

编辑&#xff5c;排版&#xff5c; 宅哥技术 ---------♥--------- Live壁纸 大家都知道这个Live壁纸在微信上传是不能动的&#xff0c;所以我把这些壁纸都发在了我的微博里面&#xff0c;这样我们保存出来的壁纸是可以动的哦&#xff01;凡是支持3D touch的手机都可以使用&…

怎么设置动态壁纸?这样做就行!

案例&#xff1a;怎么设置动态壁纸 【朋友们&#xff0c;我的壁纸一直都是静态的&#xff0c;最近感觉有点审美疲劳了&#xff0c;想换些好看的动态壁纸&#xff0c;有朋友知道应该如何设置动态壁纸吗&#xff1f;】 经常使用电脑的朋友可能会觉得一直用同一张壁纸会感觉审美…

将MSYS2 MinGW集成到Windows终端

微软开发了一款Windows终端的开源软件&#xff0c;非常好用。安装后在Win7及以上系统会在右键菜单中添加一条“在终端中打开”的命令&#xff0c;非常方便。它默认配置了Windows命令行以及PowerShell&#xff0c;如果安装了Visual Studio 2022还会配置Visual Studio 2022的命令…

python之函数(参数,匿名函数,局部变量和全局变量)

文章目录 前言一、函数的参数 1、形参和实参2、必传参数&#xff08;也叫&#xff1a;必须参数&#xff09;3、关键字传参4.、默认参数5、不定长参数6、传参的顺序二、匿名函数&#xff08;lambda函数&#xff09; 1. 定义及特点语法格式2. lambda函数的特点三、函数返回值retu…

QT 5.14 和 VS2017脱机离线安装记录

QT 5.14是最后的离线安装版本&#xff0c;都推荐这个。看了下&#xff0c;官方建议搭配 VS2017/VS2015 VS版本对于QT&#xff0c;我一直偏好社区版&#xff0c;只要编译器就够了&#xff0c;自己加上SDK目录。因为大部分工作都是在QT内完成。VS2017的离线安装比较复杂&#xff…

Git常用命令submodule

Git常用命令submodule 1、需求 当程序比较大参与开发人员较多时&#xff0c;代码管理就复杂起来。代码如果全员可见&#xff0c;可以创建 share 分支维护共用代 码&#xff0c;可以创建 core 分支维护核心算法代码&#xff0c;各进程分别占一个分支&#xff0c;定期同步 sha…

vmware15下载与安装教程

VMware VMware是一款虚拟机软件&#xff0c;可以在同一台计算机上运行多个操作系统。VMware15是VMware公司推出的最新版本&#xff0c;具有更好的性能和稳定性&#xff0c;同时支持Windows、Mac以及Linux等多种操作系统。 以下是VMware15的下载安装教程&#xff1a; 下载VMw…

Win10—VMware15虚拟机安装教程

一、下载 下载地址VMware15&#xff08;32/64&#xff09;位下载地址&#xff0c;提取码: qvry 二、安装 解压缩如下&#xff1a; 双击exe运行 点击【下一步】 勾选【我接受条款协议中的条款】&#xff0c;然后点击【下一步】。 点击【更改】更改软件的安装目录&…

完全免费PNG素材库,免费可商用~

推荐的这几个PNG素材网一定要收藏~免费可商用~ 菜鸟图库 https://www.sucai999.com/searchlist/66008----all-0-1.html?vNTYxMjky 菜鸟图库是一个为新手设计师提供免费素材的网站&#xff0c;站内有非常多设计相关素材&#xff0c;比如平面模板、UI素材、电商素材、免抠素材…

VMware15虚拟机安装教程

​​​​​关注公众号&#xff0c;免费获取资料 简介&#xff1a; VMware&#xff08;威睿&#xff09; 是全球桌面到数据中心虚拟化解决方案的领导厂商。全球不同规模的客户依靠VMware来降低成本和运营费用、确保业务持续性、加强安全性并走向绿色。VMware使企业可以采用能够解…

【转】VMware15虚拟机安装教程

https://mp.weixin.qq.com/s/Rdj5AA7aVOzFDMnXeousWg &#xff08;源于软件安装管家公众号&#xff09; VMware15&#xff08;32/64&#xff09;位下载地址&#xff1a; pan.baidu.com/s/16_JlJ31R6wR8ja_f7o9kNw 提取码: 4c94 [Windows 10/64位下载链接]&#xff1…

VMware虚拟机安装win10系统教程(巨细)

VMware安装win10流程 第一章&#xff1a;创建新虚拟机 第二章&#xff1a;典型安装与自定义安装 ​ 典型安装与自定义安装的差别&#xff1a;通常设计人员使用自定义安装&#xff08;高级&#xff09;。 1. 典型安装&#xff1a; 这种安装方式将默认选项用于所有安装设置&…

七、进程地址空间

一、环境变量 &#xff08;一&#xff09;概念 环境变量(environment variables)&#xff1a;系统当中用做特殊用途的系统变量。 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但是照样可…

bmp图片怎么转jpg格式?思路提供

BMP和JPG是两种常见的图片格式。BMP文件相对较大&#xff0c;无损压缩&#xff0c;而JPG文件则相对较小&#xff0c;有损压缩。当我们需要在保持图片质量的同时减小文件大小时&#xff0c;我们可以将BMP文件转换为JPG文件。在本文中&#xff0c;我们将介绍如何将BMP文件转换为J…