Qt学习之ui创建串口助手

一、串口简介

二、Qt编写串口助手

1、创建Qt工程

选择MinGW 64-bit

点击下一步完成,工程创建完成。

使用串口模块,需要在工程文件.pro中添加以下代码,不添加的话,会报错。

或者在core gui 后输入 serialport 也可以

2、配置UI界面 

双击打开带.ui后缀的文件

可以在右边设置窗口的大小(宽和高)

创建一个Widget界面,用于放置控件

下面框选的就是Wiget界面,可以看出里面有很多控件,这样可以方便我们控件布局

做一个串口助手,需要有接收和发送功能,这里接收功能使用接收控件实现.

选择接收控件(Plain Text Edit),拖到UI界面中。

因为接受数据是只读的,我们需要把这个控件的属性设置为只读。在右下角属性栏勾选readOnly。

设置串口号、波特率、停止位、数据位、校验位需要下拉框,所以在左边找到Combo Box,添加到UI界面中。

使用标签 Label控件作注释 

使用Line Edit作为发送控件,也就是发送数据的框

打开串口(关闭串口)、发送数据、清除接受等需要使用Push Button作为点击控件

通过以上的配置,一个基础的串口调试助手就完成了

除此之外,还可以加入复选框,使用的是Check Box控件

最终配置UI界面如下

工程文件

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QSerialPortInfo>    //提供系统中存在的串口的信息
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFile>
#include <QDebug>
#include <QTimer>MainWindow::MainWindow(QWidget *parent): QWidget(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);initPort();// 默认显示文本数据dispalyText();// 将复选框的 toggled(bool) 信号连接到槽函数connect(ui->hexDisplayChex, &QCheckBox::toggled, this, &MainWindow::on_hexDisplayChex_toggled);
}MainWindow::~MainWindow()
{delete ui;
}/****************************串口初始化******************************/
void MainWindow::initPort()
{//设置改变connect(ui->baudRateCmb, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this, [=]{auto br = ui->baudRateCmb->currentData().value<QSerialPort::BaudRate>();if (!serialPort_.setBaudRate(br)){QMessageBox::warning(this, "false", "设置波特率失败:" + serialPort_.errorString());}});connect(ui->dataBitsCmb,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,[=]{auto value = ui->dataBitsCmb->currentData().value<QSerialPort::DataBits>();if(!serialPort_.setDataBits(value)){QMessageBox::warning(this,"false","设置数据位失败:"+serialPort_.errorString());}});connect(ui->stopBitCmb,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,[=]{auto value = ui->stopBitCmb->currentData().value<QSerialPort::StopBits>();if(!serialPort_.setStopBits(value)){QMessageBox::warning(this,"false","设置停止位失败:"+serialPort_.errorString());}});connect(ui->parityCmb,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,[=]{auto value = ui->parityCmb->currentData().value<QSerialPort::Parity>();if(!serialPort_.setParity(value)){QMessageBox::warning(this,"false","设置校验位失败:"+serialPort_.errorString());}});//获取所有可用的串口auto portsInfo = QSerialPortInfo::availablePorts();for (auto& info : portsInfo){qInfo() << info.description() << info.portName() << info.systemLocation();ui->portsCmb->addItem(info.portName() + ":" + info.description(),info.portName());}//获取标准的波特率auto baudRates = QSerialPortInfo::standardBaudRates();for(auto br : baudRates){ui->baudRateCmb->addItem(QString::number(br),br);//遍历设置波特率}//设置默认的波特率ui->baudRateCmb->setCurrentText("9600");//设置停止位ui->stopBitCmb->addItem("1",QSerialPort::OneStop);ui->stopBitCmb->addItem("1.5",QSerialPort::OneAndHalfStop);ui->stopBitCmb->addItem("2",QSerialPort::TwoStop);//设置数据位ui->dataBitsCmb->addItem("5",QSerialPort::Data5);ui->dataBitsCmb->addItem("6",QSerialPort::Data6);ui->dataBitsCmb->addItem("7",QSerialPort::Data7);ui->dataBitsCmb->addItem("8",QSerialPort::Data8);ui->dataBitsCmb->setCurrentText("8");//设置校验位ui->parityCmb->addItem("NoParity   ",QSerialPort::NoParity   );  //按住ALT多行编辑ui->parityCmb->addItem("EvenParity ",QSerialPort::EvenParity );ui->parityCmb->addItem("OddParity  ",QSerialPort::OddParity  );ui->parityCmb->addItem("SpaceParity",QSerialPort::SpaceParity);ui->parityCmb->addItem("MarkParity ",QSerialPort::MarkParity );connect(&serialPort_,&QSerialPort::readyRead,this,&MainWindow::onReadyRead);timer_.callOnTimeout([=]{this->on_sendBtn_released();});//    //读取串口信息
//    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
//    {
//        qDebug()<<"Name:"<<info.portName();
//        qDebug()<<"Description:"<<info.description();
//        qDebug()<<"Manufacturer:"<<info.manufacturer();//        //这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
//        QSerialPort serial;
//        serial.setPort(info);
//        if(serial.open(QIODevice::ReadWrite))
//        {
//            //将串口号添加到cmb
//            ui->portsCmb->addItem(info.portName());
//            //关闭串口等待人为(打开串口按钮)打开
//            serial.close();
//        }
//    }//    QStringList baudList;//波特率
//        QStringList parityList;//校验位
//        QStringList dataBitsList;//数据位
//        QStringList stopBitsList;//停止位//        baudList<<"50"<<"75"<<"100"<<"134"<<"150"<<"200"<<"300"
//               <<"600"<<"1200"<<"1800"<<"2400"<<"4800"<<"9600"
//              <<"14400"<<"19200"<<"38400"<<"56000"<<"57600"
//             <<"76800"<<"115200"<<"128000"<<"256000";//        ui->baudRateCmb->addItems(baudList);
//        ui->baudRateCmb->setCurrentIndex(12);//        parityList<<"无"<<"奇"<<"偶";
//        parityList<<"标志";
//        parityList<<"空格";//        ui->parityCmb->addItems(parityList);
//        ui->parityCmb->setCurrentIndex(0);//        dataBitsList<<"5"<<"6"<<"7"<<"8";
//        ui->dataBitsCmb->addItems(dataBitsList);
//        ui->dataBitsCmb->setCurrentIndex(3);//        stopBitsList<<"1";
//        stopBitsList<<"1.5";
//        stopBitsList<<"2";//        ui->stopBitCmb->addItems(stopBitsList);
//        ui->stopBitCmb->setCurrentIndex(0);//        //设置按钮可以被按下
//        ui->openPortBtn->setCheckable(true);}/****************************串口设置******************************/
void MainWindow::on_openPortBtn_released()
{//串口是否已经打开if(serialPort_.isOpen()){serialPort_.close();ui->openPortBtn->setText("打开串口");if(timer_.isActive()){timer_.stop();}return;}//获取串口auto portName = ui->portsCmb->currentData().toString();
//    //获取波特率
//    auto baudRate = ui->baudRateCmb->currentData().value<QSerialPort::BaudRate>();
//    //获取数据位
//    auto dataBits = ui->dataBitsCmb->currentData().value<QSerialPort::DataBits>();
//    //获取停止位
//    auto stopBits = ui->stopBitCmb->currentData().value<QSerialPort::StopBits>();
//    //获取校验位
//    auto parity = ui->parityCmb->currentData().value<QSerialPort::Parity>();serialPort_.setPortName(portName);
//    serialPort_.setBaudRate(baudRate);
//    serialPort_.setDataBits(dataBits);
//    serialPort_.setStopBits(stopBits);
//    serialPort_.setParity(parity);//打开串口if(!serialPort_.open(QIODevice::ReadWrite)){QMessageBox::warning(this,"warning",portName + "open failaed:" + serialPort_.errorString());return;}else{ui->openPortBtn->setText("关闭串口");}
}//发送数据
void MainWindow::on_sendBtn_released()
{auto dataStr = ui->sendEdit->toPlainText() + (ui->sendNewLineChx->isChecked() ?"\r\n":"");//+ ui->sendNewLineChx->isChecked() ?"\r\n":""serialPort_.write(dataStr.toLocal8Bit());
}//接收函数
void MainWindow::onReadyRead()
{
//    auto data = serialPort_.readAll();
//    ui->recvEdit->setPlainText(QString::fromLocal8Bit(data));QByteArray data = serialPort_.readAll();QString receivedData = QString::fromLocal8Bit(data);  // 使用正确的编码解析数据processReceivedData(receivedData);}//接收处理函数
void MainWindow::processReceivedData(const QString& data)
{if (ui->hexDisplayChex->isChecked()) {// 如果复选框已勾选,将接收到的数据转换为十六进制并显示QString hexData = data.toLocal8Bit().toHex(' ').toUpper();ui->recvEdit->appendPlainText(hexData);} else {// 如果复选框未勾选,显示接收到的数据文本ui->recvEdit->appendPlainText(data);}
}//打开文件
void MainWindow::on_openfileBtn_released()
{auto filename = QFileDialog::getOpenFileName(this,"选择文件",QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),"txt(*.txt);;all(*.*)");if(!filename.isEmpty()){ui->fileNameEdit->setText(filename);}
}//发送文件
void MainWindow::on_sendfileBtn_released()
{auto filename = ui->fileNameEdit->text();QFile file(filename);if(!file.open(QIODevice::ReadOnly)){QMessageBox::warning(this,"warning",filename + "open failed:" + file.errorString());return;}//最好判断一下文件的编码serialPort_.write(QString::fromUtf8(file.readAll()).toLocal8Bit());}//显示十六进制或者十进制
void MainWindow::on_hexDisplayChex_toggled(bool checked)
{if (checked) {// 如果复选框被选中,显示接收数据的十六进制格式dispalyHex();} else {// 如果复选框未选中,显示接收数据的文本格式dispalyText();}
}void MainWindow::dispalyHex()
{QString currentText = ui->recvEdit->toPlainText();QString hexData = currentText.toLocal8Bit().toHex(' ').toUpper();ui->recvEdit->setPlainText(hexData);
}void MainWindow::dispalyText()
{QString currentText = ui->recvEdit->toPlainText();ui->recvEdit->setPlainText(currentText);
}//十六进制显示
//void MainWindow::on_hexDisplayChex_toggled(bool checked)
//{
//    if(checked)
//        dispalyHex();
//    else
//        dispalyText();//}//void MainWindow::dispalyHex()
//{
//    //先把数据拿出来
//    auto dataStr = ui->recvEdit->toPlainText();
//    //转成十六进制
//    auto hexData = dataStr.toLocal8Bit().toHex(' ').toUpper();//添加间隔符' '
//    //写回去
//    ui->recvEdit->setPlainText(hexData);//}//void MainWindow::dispalyText()
//{
//    //先把数据拿出来
//    auto dataStr = ui->recvEdit->toPlainText();
//    //转成文本
//    auto textData =QString::fromLocal8Bit(dataStr.toLocal8Bit());
//    //写回去
//    ui->recvEdit->setPlainText(textData);
//}void MainWindow::on_timerSendChx_toggled(bool checked)
{if(checked){timer_.start(ui->timerperiodEdit->text().toUInt());ui->timerperiodEdit->setEnabled(false);}else{timer_.stop();}
}void MainWindow::on_sendstopBtn_released()
{serialPort_.clear();if(timer_.isActive())timer_.stop();}
//清空槽函数
void MainWindow::on_clearRecvBtn_clicked()
{ui->recvEdit->clear();
}

mainwindow.h 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QWidget>
#include <QTimer>
#include <QSerialPort>        //提供访问串口的功能
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QWidget
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();void initPort();  //Alt+回车快捷键private slots:void on_openPortBtn_released();void on_sendBtn_released();void onReadyRead();void on_openfileBtn_released();void on_sendfileBtn_released();void on_hexDisplayChex_toggled(bool checked);void on_timerSendChx_toggled(bool checked);void on_sendstopBtn_released();void on_clearRecvBtn_clicked();//    void toggleHexDisplay(int state);void processReceivedData(const QString& data);private:void dispalyHex();void dispalyText();Ui::MainWindow *ui;QSerialPort serialPort_;QTimer timer_;
};
#endif // MAINWINDOW_H

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

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

相关文章

15 个适用于企业的生成式 AI 用例

作者&#xff1a;来自 Elastic Jennifer Klinger 关于生成式人工智能及其能做什么&#xff08;和不能做什么&#xff09;有很多讨论。生成式人工智能&#xff08;例如大型语言模型 - LLMs&#xff09;利用从大量训练数据中学习到的模式和结构来创建原创内容&#xff0c;而无需存…

【Web缓存】Nginx和CDN应用

目录 一.代理相关概述 1.工作机制 2.概念 3.作用 4.常用的代理服务器 二.Nginx缓存代理服务器部署 1.在三台服务器上部署nginx 2.在后端原始服务器上创建测试页面 3.完成nginx服务器配置修改 3.1.关闭两台测试机长连接并重启服务 3.2.设置nginx缓存服务器配置 三.C…

计算神经网络中梯度的核心机制 - 反向传播(backpropagation)算法(1)

计算神经网络中梯度的核心机制 - 反向传播&#xff08;backpropagation&#xff09;算法&#xff08;1&#xff09; flyfish 链式法则在深度学习中的主要应用是在反向传播&#xff08;backpropagation&#xff09;算法中。 从简单的开始 &#xff0c;文本说的就是链式法则 R …

pandas数据分析(2)

列 执行df.columns获取DataFrame列信息&#xff1a; 如果在构造DataFrame时没有提供列名&#xff0c;那么pandas会用 从0开始的数字为列编号。我们也可以为列命名&#xff0c;和为索引命名类似&#xff1a; 同样也可以重命名列名&#xff1a; 使用df.drop删除列&#xff1a; 删…

springboot解析自定义yml文件

背景 公司产品微服务架构下有十几个模块&#xff0c;几乎大部分模块都要连接redis。每次在客户那里部署应用&#xff0c;都要改十几遍配置&#xff0c;太痛苦了。当然可以用nacos配置中心的功能&#xff0c;配置公共参数。不过我是喜欢在应用级别上解决问题&#xff0c;因为并不…

华为RH2288H V2服务器,远程端口安装Linux操作系统

1、管理口 每台服务器的管理口不一样的&#xff0c;假如我的管理IP地址为&#xff1a;192.168.111.201 使用网线&#xff0c;将管理口和自己电脑连接起来&#xff0c;自己ip地址设置成和管理ip同一网段。 使用 ie 浏览器&#xff0c;如果是Edge&#xff0c;必须在Internet Exp…

如何配置Redis + Rdis在IDEA中的使用

文章目录 Step1. 下载zipStep2. 修改环境变量Step3. 启动Redis服务端Step4. 启动Redis客户端Step5. IDEA中链接Redis Step1. 下载zip 下载 Redis-x64-xxx.zip压缩包&#xff0c;解压到 E 盘后&#xff0c;将文件夹重新命名为 redis 下载地址&#xff1a;Redis下载地址 Step2…

Go 语言切片遍历地址会发生改变吗?

引言&#xff1a;今天面试的时候&#xff0c;面试官问了一道学 Go 语言的同学都会的简单代码&#xff0c;是关于 Go 语言 for 循环问题的&#xff0c;他询问了一个点&#xff0c;循环中共享变量的地址会发生改变吗&#xff1f; 相信听到这个问题的你&#xff0c;第一反应肯定是…

Webpack: 深入理解图像加载原理与最佳实践

概述 图形图像资源是当代 Web 应用的最常用、实惠的内容、装饰元素之一&#xff0c;但在 Webpack 出现之前对图像资源的处理复杂度特别高&#xff0c;需要借助一系列工具(甚至 Photoshop)完成压缩、雪碧图、hash、部署等操作。 而在 Webpack 中&#xff0c;图像以及其它多媒体…

基于MongoDB的电影影评分析

项目源码及资料 项目介绍 1、从豆瓣网爬取Top10的电影数据 爬取网址: https://movie.douban.com/top250 1.1 爬取Top10的影视信息 mv_data [] i 0 for x in soup.select(.item):i 1mv_name re.search(>([^<])<, str(x.select(.info > .hd > a > .tit…

【动态规划】2306. 公司命名

本文涉及知识点 动态规划汇总 LeetCode 2306. 公司命名 给你一个字符串数组 ideas 表示在公司命名过程中使用的名字列表。公司命名流程如下&#xff1a; 从 ideas 中选择 2 个 不同 名字&#xff0c;称为 ideaA 和 ideaB 。 交换 ideaA 和 ideaB 的首字母。 如果得到的两个新…

Python 面试【★★★★★】

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

大数据可视化实验(七):Python数据可视化

目录 一、实验目的... 1 二、实验环境... 1 三、实验内容... 1 1&#xff09;绘制带颜色的柱状图。.. 1 2&#xff09;绘制堆叠柱状图。.. 3 3&#xff09;绘制数学函数曲线图。.. 4 4&#xff09;使用seaborn绘制组合图形。... 5 5&#xff09;使用Boken绘制多个三角形…

63.ThreadLocal原理

JDK8中ThreadLocal的设计 每个Thread维护一个ThreadLocalMap,这个map的key是ThreadLocal实例本身,value才是真正要存储的值Object。 Thread -> ThreadLocalMap -> <ThreadLocal实例对象, 变量副本> jdk早期设计 ThreadLocal -> ThreadLocalMap -> <T…

vmware安装debian11

安装vmware16 下载镜像 https://repo.huaweicloud.com/debian-cd/ https://repo.huaweicloud.com/debian-cd/11.7.0/amd64/iso-dvd/ 安装 安装完成之后重启&#xff0c;输入账号密码进入&#xff0c;安装ssh服务器即可使用

ManicTime(屏幕时间统计工具) 专业版值得购买吗

ManicTime 是 Windows 平台上&#xff0c;一款支持跟踪、标记用户在每个软件上所花时间的工具&#xff0c;它能自动归类生成时间使用报表&#xff0c;帮助用户分析及改善工作效率。 ManicTime 不仅会在后台记录、统计所有窗口的使用时间&#xff0c;还能自动截图存档到本地&a…

设计模式 - 原型模式,就该这样学!

目录 开始 为什么要引入原型模式 原型模式概述 原型模式代码实现&#xff08;浅拷贝&#xff09; 浅拷贝和深拷贝的区别 原型模式代码实现&#xff08;深拷贝&#xff09; 方式一&#xff1a;直接 copy 方式二&#xff1a;序列化和反序列化&#xff08;推荐&#xff09…

LeetCode 1527, 54,114

目录 1527. 患某种疾病的患者题目链接表要求知识点思路代码 54. 螺旋矩阵题目链接标签思路代码 114. 二叉树展开为链表题目链接标签前序遍历思路代码 前驱思路代码 1527. 患某种疾病的患者 题目链接 1527. 患某种疾病的患者 表 表Patients的字段为patient_id、patient_name…

C++ | Leetcode C++题解之第205题同构字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isIsomorphic(string s, string t) {unordered_map<char, char> s2t;unordered_map<char, char> t2s;int len s.length();for (int i 0; i < len; i) {char x s[i], y t[i];if ((s2t.coun…

Webpack: 7 款常用的性能分析工具

概述 Webpack 最大的优势在于它的功能非常强大、全面&#xff0c;加之繁荣活跃的组件生态&#xff0c;已经足够应对几乎所有 Web 构建需求&#xff0c;包括&#xff1a;SPA、MPA、SSR、桌面应用、Node 程序、WebAssemsbly、PWA、微前端等等&#xff0c;所以即使在近几年工程化…