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,一经查实,立即删除!

相关文章

Java并发编程-volatile关键字详解及案例实战

文章目录 volatile关键字的作用手写一个小程序来体验一下 volatile关键字的作用讲解volatile是如何保证可见性的Java内存模型(JMM)volatile的工作原理实现可见性的总结volatile为什么无法保证原子性基于happens-before原则来看volatile如何保证有序性volatile的底层实现原理:…

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…

简单介绍 Kamailio cfg_rpc 模块

记得先加载 cfg_rpc 模块 loadmodule "cfg_rpc.so" kamailio 起来之后 运行 kamcmd cfg.list 可以得到&#xff1a; dispatcher: probing_threshold dispatcher: inactive_threshold dispatcher: ping_reply_codes rtpengine: rtpengine_disable_tout rtpengine: a…

计算神经网络中梯度的核心机制 - 反向传播(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; 删…

《昇思25天学习打卡营第3天 | mindspore DataSet 数据集的常见用法》

1. 背景&#xff1a; 使用 mindspore 学习神经网络&#xff0c;打卡第三天&#xff1b; 2. 训练的内容&#xff1a; 使用 mindspore 的常见的数据集 DataSet 的使用方法&#xff1b; 3. 常见的用法小节&#xff1a; 数据集加载 train_dataset MnistDataset("MNIST_…

考研11408相关资料整理

文章目录 考研114081. 代码解析&#xff1a;2. 考试难度&#xff1a;3. 考试目标&#xff1a;4. 备考建议&#xff1a; 考研资料整理考研数学一用到的书籍1. 教材类&#xff1a;2. 复习全书类&#xff1a;3. 真题、习题、模拟题类&#xff1a; 考研英语一用到的书籍1. 词汇书&a…

云上MongoDB常见索引问题及最优索引规则大全

1、云上用户存在索引共性问题 无用索引&#xff1b; 重复索引&#xff1b; 索引不是最优&#xff1b; 对索引理解有误等。 2、执行计划 判断索引选择及不同索引执行家伙信息可以通过explain操作获取&#xff0c;MongoDB通过explain来获取SQL执行过程信息&#xff0c;当前…

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…

AI学习指南机器学习篇-随机森林的优缺点

AI学习指南机器学习篇-随机森林的优缺点 引言 机器学习是人工智能领域的重要分支&#xff0c;其中随机森林(Random Forest)算法以其高性能和广泛应用而备受瞩目。然而&#xff0c;就像任何其他算法一样&#xff0c;随机森林也有其优缺点。本文将深入探讨随机森林算法的优势和…

如何配置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…

嵌入式网页服务实现

嵌入式网页服务的实现方式主要可以归纳为以下几种&#xff1a; 单片机Webchip网关&#xff1a; Webchip&#xff1a;作为专用网络接口芯片&#xff0c;独立于单片机与网关&#xff0c;通过SPI接口与MCU进行指令交互&#xff0c;并通过RS232、USB、Modem等接口与PC作为网关进行通…

LInux后台运行程序

测试c代码 #include <stdio.h> #include <unistd.h> int main() {for (int i;; i) {printf("b数值 %d\n", i);fflush(stdout);sleep(3);} }使用CtrlZ可以将当前正在运行的程序放到后台并暂停它。如果你想要继续这个暂停的程序&#xff0c;可以使用fg命令…

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

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

开发指南037-链式编程

平台提倡链式编程。所谓链式编程就是把过去多行的语句通过.符号串联为一句&#xff08;注意为了可读性&#xff0c;往往通过在.符号处换行&#xff09;&#xff0c;直观的对比如下&#xff1a; 非链式&#xff1a; object.setPropertyA(A); object.setPropertyB(B); object.set…

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…

c++和c#和c语言

C、C# 和 C 语言之间有关系&#xff0c;但它们在设计目标、应用领域和语法特性上也有显著的区别。以下是它们之间的关系和主要区别&#xff1a; 关系 C 语言&#xff1a; 基础&#xff1a;C 语言是一种通用的过程式编程语言&#xff0c;开发于20世纪70年代&#xff0c;用于系统…