QT-串口工具

news2024/11/18 5:27:53

一、演示效果

请添加图片描述

二、关键程序

#include "mainwindow.h"
#include "ui_mainwindow.h"


#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    listPlugins(QList<TabPluginInterface *>()),
    translator(new QTranslator())
{
    ui->setupUi(this);

    tabCOMSimple = new TabCOMSimple(this);
    ui->tabMain->addTab(tabCOMSimple, tr("Simple"));

    tabAdvanced = new TabAdvanced(this);
    ui->tabMain->addTab(tabAdvanced, tr("Advanced"));

    decoder = new Decoder(this, tabAdvanced->getListProtocals(), tabAdvanced->getEndianess());

    // [start] Data stream connections.
    connect(decoder, &Decoder::rawDataReady, tabCOMSimple, &TabCOMSimple::rawDataReady);
    connect(decoder, &Decoder::frameReady, tabAdvanced, &TabAdvanced::frameDataReady);
    // [End]

    // [Start] Plugins
    connect(ui->actionLoad_Plugin, &QAction::triggered, this, &MainWindow::onLoadPluginTriggered);
    connect(decoder, &Decoder::frameReady, this, &MainWindow::onDecodedDataReady);

    QString folderString = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/QSerial Socket Amigo";
    QFileInfo folder(folderString);
    if (!folder.exists())
        QDir().mkdir(folderString);
    folderString.append("/plugins");
    QFileInfo pluginsFolder(folderString);
    if (!pluginsFolder.exists())
        QDir().mkdir(folderString);
    // [End]

    // [Start] i18n
    connect(ui->actionEnglish, &QAction::triggered, this, &MainWindow::onActionEnglishTriggered);
    ui->menuLanguage->addAction(tr(u8"简体中文"), this, &MainWindow::onActionChineseTriggered);
    // [End]

    ui->groupNetProperties->setDisabled(true);
    connect(ui->radioSerial, &QRadioButton::clicked, this, &MainWindow::onConnectionTypeChanged);
    connect(ui->radioNetSocket, &QRadioButton::clicked, this, &MainWindow::onConnectionTypeChanged);
    connect(ui->buttonOpen, &QPushButton::clicked, this, &MainWindow::openConnection);

    serialDevice = new SerialDevice(this, ui->comboPorts, ui->buttonRefreshPorts,
                                          ui->comboBaudrate, ui->comboDataBits,
                                          ui->comboParity, ui->comboStopBits,
                                          ui->comboFlowControl);
    netSocketDevice = new NetSocketDevice(this, ui->inputNetIPAddr, ui->inputNetPort,
                                          ui->radioNetTypeTCP, ui->radioNetTypeUDP,
                                          ui->radioNetRoleClient, ui->radioNetRoleServer);
    connect(serialDevice, &SerialDevice::connected, this, &MainWindow::onDeviceConnected);
    connect(netSocketDevice, &SerialDevice::connected, this, &MainWindow::onDeviceConnected);
    connect(serialDevice, &SerialDevice::errorDisconnected, this, &MainWindow::onDeviceErrorDisconnected);
    connect(netSocketDevice, &SerialDevice::errorDisconnected, this, &MainWindow::onDeviceErrorDisconnected);
    commDevice = serialDevice;

    // [start] Log stream connections.
    connect(tabCOMSimple, &TabCOMSimple::log, this, &MainWindow::log);
    connect(netSocketDevice, &NetSocketDevice::log, this, &MainWindow::log);
    // [end]
	translateTo("zh");
	
	this->setWindowTitle(u8"串口工具");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onConnectionTypeChanged(bool isChecked)
{
    Q_UNUSED(isChecked)

    if (ui->radioSerial->isChecked()) {
        ui->groupNetProperties->setDisabled(true);
        ui->groupSerialProperties->setEnabled(true);
        commDevice = serialDevice;
    } else if (ui->radioNetSocket->isChecked()) {
        ui->groupNetProperties->setEnabled(true);
        ui->groupSerialProperties->setDisabled(true);
        commDevice = netSocketDevice;
    }
}

void MainWindow::closeDevice()
{
    commDevice->close();
    ui->groupConnSel->setEnabled(true);
    ui->buttonOpen->setText(tr("Open Connection"));
    tabAdvanced->setAllowRunning(false);
}

void MainWindow::openConnection()
{
    if (ui->groupConnSel->isEnabled()) {
        // This acts like sending connect command, device will signals conncted if so.
        int ret = commDevice->open();
        if (ret != 0) {
            return;
        }
    } else {
        closeDevice();
    }
}

// Only when device is really connected.
void MainWindow::onDeviceConnected()
{
    tabCOMSimple->bindIODevice(commDevice->ioDevice);
    decoder->setConnection(commDevice->ioDevice);
    ui->groupConnSel->setDisabled(true);
    ui->buttonOpen->setText(tr("Close Connection"));
    tabAdvanced->setAllowRunning(true);
}

void MainWindow::onDeviceErrorDisconnected()
{
    closeDevice();
}

void MainWindow::log(QString str)
{
    ui->textLog->append(str);
}

void MainWindow::onLoadPluginTriggered()
{
    QString pluginsFolder = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/QSerial Socket Amigo/plugins";
#if defined(Q_OS_WIN)
    QString type = tr("Dynamic Linked Library (*.dll)");
#elif defined (Q_OS_LINUX)
    QString type = tr("Shared Library (*.so)");
#else
    //Not supporting Mac.
    Q_ASSERT(false);
#endif
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("Select Plugin to Load"),
        pluginsFolder,
        type);
    if (fileName.isEmpty())
        return;
    else {
        QPluginLoader loader(fileName);
        QObject *pluginObject = loader.instance();
        if (pluginObject) {
            TabPluginInterface *plugin = qobject_cast<TabPluginInterface *>(pluginObject);
            plugin->setConnection(currentConnection);
            listPlugins.append(plugin);
            QWidget *widget = new QWidget();
            widget->setLayout(plugin->getLayout());
            ui->tabMain->addTab(widget, plugin->getName());
            ui->tabMain->setCurrentIndex(ui->tabMain->count() - 1);
        } else
            QMessageBox::warning(this, tr("error"), tr("plugin read error"));
    }
}

void MainWindow::onDecodedDataReady(int id, QList<double> listValues)
{
    for (auto plugin : listPlugins)
        plugin->onFrameUpdated(id, listValues);
}

// Two characters locale, eg: en, zh, de.
void MainWindow::translateTo(QString locale)
{
    QString qmPath = qApp->applicationDirPath().append("/Serial-Amigo_");
    translator->load(qmPath.append(locale).append(".qm"));
    qApp->installTranslator(translator);
	
}

void MainWindow::retranslateUi()
{
    ui->tabMain->setTabText(1, QCoreApplication::translate("MainWindow", "Simple"));
    ui->tabMain->setTabText(2, QCoreApplication::translate("MainWindow", "Advanced"));
    ui->comboParity->setItemText(0, QCoreApplication::translate("MainWindow", "NoParity"));
    ui->comboParity->setItemText(1, QCoreApplication::translate("MainWindow", "EvenParity"));
    ui->comboParity->setItemText(2, QCoreApplication::translate("MainWindow", "OldParity"));
    ui->comboParity->setItemText(3, QCoreApplication::translate("MainWindow", "SpaceParity"));
    ui->comboParity->setItemText(4, QCoreApplication::translate("MainWindow", "MarkParity"));
    ui->comboFlowControl->setItemText(0, QCoreApplication::translate("MainWindow", "No"));
    ui->comboFlowControl->setItemText(1, QCoreApplication::translate("MainWindow", "Hard"));
    ui->comboFlowControl->setItemText(2, QCoreApplication::translate("MainWindow", "Soft"));
}

void MainWindow::onActionChineseTriggered()
{
    translateTo("zh");
}

void MainWindow::onActionEnglishTriggered()
{
    translateTo("en");
}

void MainWindow::changeEvent(QEvent *event)
{
    switch (event->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        retranslateUi();
        break;
    default:
        break;
    }
    QMainWindow::changeEvent(event);
}

void MainWindow::updatePluginConnection()
{
    for (auto plugin : listPlugins)
        plugin->setConnection(commDevice->ioDevice);
}

三、下载链接

https://download.csdn.net/download/u013083044/88867720

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

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

相关文章

C++笔记:二叉搜索树(Binary Search Tree)

文章目录 二叉搜索树的概念二叉搜索树操作1. 框架搭建2. 遍历3. 查找迭代实现递归实现 4. 插入迭代实现递归实现 5. 删除迭代实现递归实现 6. 析构与销毁7. 拷贝构造与赋值重载 二叉搜索树的应用二叉搜索树的性能分析二叉搜索树模拟实现源码 二叉搜索树的概念 二叉搜索树又称二…

5G网络(接入网+承载网+核心网)

5G网络&#xff08;接入网承载网核心网&#xff09; 一、5G网络全网架构图 这张图分为左右两部分&#xff0c;右边为无线侧网络架构&#xff0c;左边为固定侧网络架构。 无线侧&#xff1a;手机或者集团客户通过基站接入到无线接入网&#xff0c;在接入网侧可以通过RTN或者IP…

欢迎 Gemma: Google 最新推出开源大语言模型

今天&#xff0c;Google 发布了一系列最新的开放式大型语言模型 —— Gemma&#xff01;Google 正在加强其对开源人工智能的支持&#xff0c;我们也非常有幸能够帮助全力支持这次发布&#xff0c;并与 Hugging Face 生态完美集成。 Gemma 提供两种规模的模型&#xff1a;7B 参数…

js之事件代理/事件委托

事件代理也叫事件委托&#xff0c;原理&#xff1a;利用DOM元素的事件冒泡&#xff0c;指定一个事件的处理程序就可以管理某一类型的所有事件。 事件冒泡和事件捕获 如上图所示&#xff0c;事件传播分成三个阶段&#xff1a; 捕获阶段&#xff1a;从window对象传导到目标节点&…

【Qt】信号和槽机制

目录 一、认识信号和槽 二、connect函数 三、自定义槽函数 四、自定义信号 五、带参数的信号和槽 六、信号和槽断开连接 七、信号和槽存在的意义 八、Lambda表达式定义槽函数 一、认识信号和槽 概述 在Qt中&#xff0c;用户和控件的每次交互过程称为一个事件。如"…

【Spring】SpringBoot 单元测试

目 录 一.什么是单元测试&#xff1f;二.单元测试有哪些好处&#xff1f;三.Spring Boot 单元测试使用单元测试的实现步骤 一.什么是单元测试&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证的过程就叫单元…

如何查看电脑使用记录?保障个人隐私和安全

查看电脑使用记录是了解电脑活动的一种重要方式&#xff0c;可以帮助用户追踪应用程序的使用情况、登录和关机时间、文件的访问记录等。在本文中&#xff0c;我们将介绍如何查看电脑使用记录的三个方法&#xff0c;以分步骤详细说明如何查看电脑使用记录&#xff0c;帮助用户更…

07 MyBatis之高级映射 + 懒加载(延迟加载)+缓存

1. 高级映射 例如有两张表, 分别为班级表和学生表 自然, 一个班级对应多个学生 像这种数据 , 应该如果如何映射到Java的实体类上呢? 这就是高级映射解决的问题 以班级和学生为例子 , 因为一个班级对应多个学生 , 因此学生表中必定有一个班级编号字段cid 但我们在学生的实体…

MT8791迅鲲900T联发科5G安卓核心板规格参数_MTK平台方案定制

MT8791安卓核心板是一款搭载了旗舰级配置的中端手机芯片。该核心板采用了八核CPU架构设计&#xff0c;但是升级了旗舰级的Arm Cortex-A78核心&#xff0c;两个大核主频最高可达2.4GHz。配备了Arm Mali-G68 GPU&#xff0c;通过Mali-G88的先进技术&#xff0c;图形处理性能大幅提…

PyTorch:transforms.Normalize()函数详解

PyTorch&#xff1a;transforms.Normalize()函数详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望得到您的订阅和…

华为配置WDS手拉手业务示例

配置WDS手拉手业务示例 组网图形 图1 配置WDS手拉手业务示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 企业用户通过WLAN接入网络&#xff0c;以满足移动办公的最基本需求。但企业考虑到AP通过有线部署的成本较高&#xff0c;所以通过建立…

智慧公厕是什么?智慧公厕是构建智慧城市的环境卫生基石

随着城市化进程的不断加速&#xff0c;城市人口密度和流动性也逐渐增大&#xff0c;对城市公共设施的需求与日俱增。而在这些公共设施中&#xff0c;公厕作为城市基础设施中不可或缺的一环&#xff0c;对城市的环境卫生和市民生活质量起着举足轻重的作用。如何提高公厕的管理效…

ChatGPT plus 的平替:9个可以联网的免费AI搜索引擎

ChatGPT plus 的平替&#xff1a;9个可以联网的免费AI搜索引擎。 由于ChatGPT 训练数据截止到2021年9月&#xff0c;在该时间点之后发生的事件&#xff0c;ChatGPT均无法给出答复。所以&#xff0c;大家现在都非常期待ChatGPT能够联网&#xff0c;访问实时的信息。 ChatGPT pl…

谷歌gemma2b windows本地cpu gpu部署,pytorch框架,模型文件百度网盘下载

简介 谷歌DeepMind发布了Gemma,这是一系列灵感来自用于Gemini相同研究和技术的开放模型。开放模型适用于各种用例,这是谷歌非常明智的举措。有2B(在2T tokens上训练)和7B(在6T tokens上训练)模型,包括基础和指令调整版本。在8192个token的上下文长度上进行训练。允许商业使…

Linux之ACL权限管理

文章目录 1.ACL权限介绍二、操作步骤1. 添加测试目录、用户、组&#xff0c;并将用户添加到组2. 修改目录的所有者和所属组3. 设定权限4. 为临时用户分配权限5. 验证acl权限6. 控制组的acl权限 1.ACL权限介绍 每个项目成员有一个自己的项目目录&#xff0c;对自己的目录有完全…

Java Stream API的二度深入

Java Stream API的二度深入 前言 为什么会写这样一篇文章呢&#xff1f; 1.面试的时候&#xff0c;一位前辈对我这方面有过一次提问&#xff0c;我随口回答&#xff0c;前辈很信任我&#xff0c;以此文致敬前辈&#xff01; 2.去回顾&#xff0c;去扎实&#xff0c;对得起前辈的…

Spring及工厂模式概述

文章目录 Spring 身世什么是 Spring什么是设计模式工厂设计模式什么是工厂设计模式简单的工厂设计模式通用的工厂设计 总结 在 Spring 框架出现之前&#xff0c;Java 开发者使用的主要是传统的 Java EE&#xff08;Java Enterprise Edition&#xff09;平台。Java EE 是一套用于…

SwiftUI 支持拖放功能的集合视图(Grid)如何捕获手指按下并抬起这一操作

功能需求 假设我们开发了一款 SwiftUI 应用,其中用户可以通过拖放 Grid 中的 Cell 来完成一些操作。现在,我们希望用户在某个 Cell 被按下并随后抬起手指时得到通知,这能够实现吗? 如上图所示,我们准确地捕获到了手指在 Grid 的 Cell 上按下再抬起这一操作!那么它是如何…

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习四(leetcode真题剖析)

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习四 01.解数独02.单词搜索03.黄金矿工04.不同路径 III 01.解数独 题目链接&#xff1a;https://leetcode.cn/problems/sudoku-solver/ 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&am…

亿道丨三防平板丨加固平板丨为零售业提供四大优势

随着全球经济的快速发展&#xff0c;作为传统行业的零售业也迎来了绝佳的发展机遇&#xff0c;在互联网智能化的大环境下&#xff0c;越来越多的零售企业选择三防平板电脑作为工作中的电子设备。作为一种耐用的移动选项&#xff0c;三防平板带来的不仅仅是坚固的外壳。坚固耐用…