PyQT——URAT串口调试助手(上位机界面)

news2024/11/25 2:33:15
页面实现效果:

main.py
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
from ui.Ui_main_window import Ui_MainWindow
from views.serial_assist_widget import *


class MainWidget(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('自定义窗口标题')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        # 初始化UI界面
        self.init_ui()

    def init_ui(self):
        self.ui.tabWidget.addTab(SerialAssistWidget(self),"串口助手工具")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = MainWidget()
    widget.show()
    sys.exit(app.exec_())
serial_assist_widget.py
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import threading
sys.path.append('../')
from ui.Ui_serial_assist_widget import Ui_SerialAssistWidget
from views.serial_setting_dialog import SettingDialog
from drivers.driver_serial import *


class SerialAssistWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)       
        self.ui = Ui_SerialAssistWidget()
        self.ui.setupUi(self)

        self.sp = None
        
        # 设备列表默认为空
        self.device_port = []
        
        # 打开页面要扫描设备并显示
        self.refresh_device_slot()
        
        # 点击事件
        self.init_ui()
        
    def init_ui(self):
        # 波特率设置按钮信号与槽函数
        self.ui.btn_setting.clicked.connect(self.show_dialog_slot)
        # 设备刷新按钮信号与槽函数
        self.ui.btn_refersh.clicked.connect(self.refresh_device_slot)
        # 链接设备按钮信号与槽函数
        self.ui.btn_connect.clicked.connect(self.btn_connect_slot)
        # 发送数据按钮信号与槽函数
        self.ui.btn_send.clicked.connect(self.btn_send_slot)
        # 清空数据发送按钮信号与槽函数
        self.ui.pushButton_4.clicked.connect(self.clear_send_text)
        # 清空数据接受按钮信号与槽函数
        self.ui.pushButton_3.clicked.connect(self.clear_recv_text)
        
    
    def clear_send_text(self):
        self.ui.edit_send.clear()
        
    def clear_recv_text(self):
        self.ui.edit_recv.clear()
        
    def btn_send_slot(self):
        if not self.sp:
            QMessageBox.warning(self,"警告","请先链接设备")
            return
        send_text = self.ui.edit_send.toPlainText()
        if send_text == '':
            QMessageBox.warning(self,"警告","请输入要发送的内容")
            return
        self.sp.write(send_text.encode("utf-8"))
        # 在末尾必须加上换行符,否则不能立即收到
        self.sp.write(b'\n')
        
        
    def btn_connect_slot(self):
        # 如果设备未选择,则弹出警告提示
        if not self.device_port:
            QMessageBox.warning(self,"警告","请选择设备")
            return
        # 如果self.sp为真说明已经链接了,再次点击要断开链接
        if self.sp:
            self.sp.close()
            self.ui.btn_connect.setText("点击链接")
            self.ui.label_status.setPixmap(QPixmap(':/icon/disc'))
            self.sp=None
            return
            
        # 收集波特率和设备信息
        baud = self.ui.cb_baud.currentText()
        device_index = self.ui.cb_device.currentIndex()
        print(device_index,type(device_index))
        print(self.device_port)
        device_name = self.device_port[device_index][0]
        
        
        # 链接设备,成功则设置按钮状态与图标,失败则弹出警告
        self.sp = SerialDevice(device_name,int(baud))
        res, msg = self.sp.open()
        if not res:
            QMessageBox.warning(self,"警告",msg)
            return
        # 设置按钮状态与图标
        self.ui.btn_connect.setText("断开链接(已链接)")
        self.ui.label_status.setPixmap(QPixmap(':/icon/connect'))
        
        # 链接成功后就应开启子线程接受数据
        t = threading.Thread(target=self.recv_data,daemon=True)
        t.start()
        
    def recv_data(self):
        while True:
            data = self.sp.readline()
            # 去掉末尾的换行符
            data = data[:-1].decode('utf-8')
            self.ui.edit_recv.append(data)
            
    
    def refresh_device_slot(self):
        self.device_port = scan_serial_ports()
        print(self.device_port)
        if len(self.device_port)>0:
            for device,description in self.device_port:
                self.ui.cb_device.addItem(description)
            # 设置默认选择第一个
            self.ui.cb_device.setCurrentIndex(0)
        
    def show_dialog_slot(self):
        self.dialog = SettingDialog(self)
        self.dialog.signal.connect(self.dialog_slot)
        self.dialog.exec_()
        
    def dialog_slot(self,bt,data_bite):
        # 将信号中的bt同步到串口助手页面
        self.ui.cb_baud.setCurrentText(bt)
        


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = SerialAssistWidget()
    widget.show()
    sys.exit(app.exec_())
serial_setting_dialog.py
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
sys.path.append("../")
from ui.Ui_serial_setting_dialog import Ui_Dialog


class SettingDialog(QDialog):
    setting_signal = pyqtSignal(str,str)
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('自定义窗口标题')
        # 初始化UI界面
        
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        
        self.init_ui()
        
        
    def btn_ok_slot(self):
        bt = self.ui.cb_bt.currentText()
        data = self.ui.cb_data.currentText()
        self.setting_signal.emit(bt,data)
        self.close()
        
        
    def init_ui(self):
        self.ui.btnOk.clicked.connect(self.btn_ok_slot)
        self.ui.btnCancel.clicked.connect(self.close)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = SettingDialog()
    widget.show()
    sys.exit(app.exec_())

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

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

相关文章

图的学习

图的基本概念和术语 图的定义:图是由顶点的有穷非空集合和顶点之间的边的集合组成的,G表示,V是图G中顶点的集合,E是图G中边的集合 无向图:任意两点的边都是无向边组成的图(无向边:&#xff08…

Java 的 Map 與 List

通過重新new 一個ArrayList 轉化 resTask.setList(new ArrayList<Group>(custMap.values())); 无序的Map List 有序的数据放到Map&#xff0c;就变成无序。 List排序 按照code 的字母进行排序A-Z resTask.getListData().sort(Comparator.comparing(Gmer::getCode));…

配置nginx作为静态文件托管服务器

下载nginx windows上是个压缩包 解压后, 使用命令行输入 nginx 进行启动 nginx -s stop 进行停止 nginx -s status 查看状态 可以配置一下环境变量 主要是配置文件, windows的nginx配置文件在 conf文件夹下 在http标签下 添加如下配置 其他地方不用更改,保持原样即可, 以…

[GN] 23种设计模式 —— 常见设计模式学习总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言创建型模式 —— 创建的艺术结构型模式 —— 组合的艺术适配器模式 -- 不兼容结构的协调对象适配器类适配器模式优缺点适用场景 组合模式 -- 树形结构的处理例子…

Springboot整合Websocket实现ws和wss连接

1. 引入pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.7.10</version> </dependency>2. 新建websocket配置文件 import org.springf…

ElementUI Form:Radio 单选框

ElementUI安装与使用指南 Radio 单选框 点击下载learnelementuispringboot项目源码 效果图 el-radio.vue 页面效果图 项目里el-radio.vue代码 <script> export default {name: el_radio,data() {return {radio: 1,radio2: 2,radio3: 3,radio4: 上海,radio5: 上海,ra…

【JAVA】单例模式的线程安全性

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 我的其他博客 正文 老生常谈的问题了&#xff0c;首先要说的是单例模式的线程安全意味着&#xff1a;某个类的实例在多线程环境 下只会被…

Codeforces Round 922 (Div. 2) (A~B)

A. Brick Wall 读题不谨慎翻车半小时&#xff0c;警惕黑体加粗的单词&#xff0c;真的很重要。 给你n高&#xff0c;m宽的方框&#xff0c;往里面放 1*k 大小的砖头&#xff0c;k自己选&#xff0c;但是>2&#xff0c;塞满方框的情况并且不超出边界&#xff0c;输出最大的…

(M)UNITY三段攻击制作

三段攻击逻辑 基本逻辑&#xff1a; 人物点击攻击按钮进入攻击状态&#xff08;bool isAttack&#xff09; 在攻击状态下&#xff0c; 一旦设置的触发器&#xff08;trigger attack&#xff09;被触发&#xff0c;设置的计数器&#xff08;int combo&#xff09;查看目前攻击…

【计算机网络】网络的网络

网络的网络 客户 customer 接入ISP提供商 provider 全球承载ISP多个ISP的层级结构 第一层ISP &#xff08;tier-1 ISP &#xff09; 位于顶部 区域ISP &#xff08;reginal ISP&#xff09;Level 3通信 &#xff0c;AT&T&#xff0c;Sprint &#xff0c;NTT存在点&#x…

交叉注意力融合时域、频域特征的FFT + CNN-Transformer-CrossAttention轴承故障识别模型

目录 往期精彩内容&#xff1a; 前言 1 快速傅里叶变换FFT原理介绍 第一步&#xff0c;导入部分数据 第二步&#xff0c;故障信号可视化 第三步&#xff0c;故障信号经过FFT可视化 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 3 交叉注意力机制 …

【机器学习300问】21、什么是激活函数?常见激活函数都有哪些?

在我写的上一篇文章中介绍了感知机&#xff08;单个神经元&#xff09;的构成&#xff0c;其中就谈到了神经元会计算传送过来的信号的总和&#xff0c;只有当这个总和超过了某个界限值时&#xff0c;才会输出值。这也称为“神经元被激活”。如果想对神经网络是什么有更多了解的…

人工智能是哪个专业

人工智能是一个以计算机科学为基础&#xff0c;由计算机、心理学、哲学等多学科交叉融合的交叉学科、新兴学科。其研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学&#xff0c;企图了解智能的实质&#xff0c;并生产出一种新的能以人类…

机器学习——绪论总结

目录 一、引入 二、基本术语 三、假设空间与归纳偏 四、模型选择 一、引入 机器学习&#xff1a;通过计算手段&#xff0c;得出具有能够自我修改、完善能力的模型&#xff0c;利用经验改善系统自身性能。算法使用数据得到模型的过程即称为学习&#xff0c;或训练 流程&…

uni-app app引入天地图

话不多说咸鱼来了 <template><view><div class"mapBox" style"width: 100%; height: 100vh;background: #ddc0c0;" id"mapId" ></div></view> </template> <script module"test" lang"r…

vue使用antv-x6 绘制流程图DAG图(二)

代码&#xff1a; <template><div class"graph-wrap" click.stop"hideFn"><Toobar :graph"graph"></Toobar><!-- 小地图 --><div id"minimap" class"mini-map-container"></div>…

Security ❀ TCP异常报文详解

文章目录 1. TCP Out-Of-Order2. TCP Previous Segment Lost3. TCP Retransmission4. TCP Dup Ack XXX#X5. TCP Windows Update6. TCP Previous segment not captured7. 异常案例分析 TCP协议中seq和ack seq的联系&#xff1a; id4的http请求报文由客户端发向服务器&#xff0…

C++ 数论相关题目 台阶-Nim游戏

现在&#xff0c;有一个 n 级台阶的楼梯&#xff0c;每级台阶上都有若干个石子&#xff0c;其中第 i 级台阶上有 ai 个石子(i≥1 )。 两位玩家轮流操作&#xff0c;每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中&#xff08;不能不拿&#xff09;。 已经拿到地面…

JAVA处理类似饼状图占比和100%问题,采用最大余额法

前言&#xff1a; 在做数据统计报表的时候&#xff0c;有两种方式解决占比总和达不到100%或者超过100%问题。 第一种方式是前端echart图自带的算分框架。 第二种方式是java后端取处理这个问题。 现存问题&#xff1a; 前端通过饼状图的方式去展示各个分类的占比累加和为100%问题…

vue前端页面时间显示问题解决方法

解决方法&#xff0c; <template slot-scope"scope"><span>{{ parseTime(scope.row.boxClosingOnlineTime, {y}-{m}-{d} {h}:{i}:{s}) }}</span> </template> 刷新页面&#xff1a; 此外&#xff0c;使用JsonFormat(pattern "yyyy-M…