QT教程demo之串口助手代码设计实现

news2024/11/15 11:17:54

关注WeChat Official Account 南山府嵌入式获取更多精彩
我创建了一个群关注V号后加入。因为这里不允许添加二维码

代码:QT_Pr

1-QT开发串口助手需要的基本文件

在QT6开发串口助手时,通常需要以下头文件:

#include <QSerialPort>
#include <QSerialPortInfo>
#include <QString>
#include <QByteArray>
#include <QDebug>

其中,QSerialPortQSerialPortInfo是用于访问串口和串口信息的类,QStringQByteArray是用于处理字符串的类,QDebug是用于输出调试信息的类。
需要注意的是,需要在.pro文件中进行引用:

QT += serialport
在.pro文件中添加该语句可以引用QT的串口库。

2-串口设置

2-1 串口扫描

2.1.1 代码设计

我们需要知道我们电脑上有哪些串口。所以需要对串口进行一个扫描的代码。

void main_frame::portNameScan(void)
{
    serialPort = new QSerialPort(this);

    // 扫描本机的串口,并且添加到下拉框里
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QString portName=info.portName();
        QString description=info.description();
        ui->serial_numcomboBox->addItem(portName + " (" + description + ")", portName);
        QListView *view = qobject_cast<QListView *>(ui->serial_numcomboBox->view());
        if (view)
        {
            view->setMinimumWidth(180);
        }
        qDebug()<<portName<<description;
    }

}

2.1.2 代码分析

这段代码的作用是扫描本机可用的串口,并将它们的名称和描述添加到 ui->serial_numcomboBox 下拉框中。

具体来说,代码中:

创建了一个 QSerialPort 对象 serialPort
通过 QSerialPortInfo::availablePorts() 静态函数获取可用的串口信息列表,并使用 foreach 循环遍历每个串口信息。
对于每个串口信息,获取其名称和描述,然后将它们作为下拉框中的一项添加到 ui->serial_numcomboBox 中。其中,addItem() 方法的第一个参数是显示在下拉框中的文本,第二个参数是该项的值。
通过 qobject_cast 函数将下拉框的视图转换为 QListView 对象,并设置视图的最小宽度为 180 像素。
使用 qDebug() 输出该串口的名称和描述。

2.1.3运行图

在这里插入图片描述

2.2 波特率

2.2.1 代码设计

//头文件定义
    enum BaudRateType
    {
        BaudRateCustom = -1,
        BaudRate1200 = 1200,
        BaudRate2400 = 2400,
        BaudRate4800 = 4800,
        BaudRate9600 = 9600,
        BaudRate19200 = 19200,
        BaudRate38400 = 38400,
        BaudRate57600 = 57600,
        BaudRate115200 = 115200

    };

void main_frame::serialBaundRate(void)
{
    ui->serial_BaudComboBox->addItem(QStringLiteral("自定义"),BaudRateCustom);
    ui->serial_BaudComboBox->addItem(QStringLiteral("1200"), BaudRate1200);
    ui->serial_BaudComboBox->addItem(QStringLiteral("2400"), BaudRate2400);
    ui->serial_BaudComboBox->addItem(QStringLiteral("4800"), BaudRate4800);
    ui->serial_BaudComboBox->addItem(QStringLiteral("9600"), BaudRate9600);
    ui->serial_BaudComboBox->addItem(QStringLiteral("19200"), BaudRate19200);
    ui->serial_BaudComboBox->addItem(QStringLiteral("38400"), BaudRate38400);
    ui->serial_BaudComboBox->addItem(QStringLiteral("57600"), BaudRate57600);
    ui->serial_BaudComboBox->addItem(QStringLiteral("115200"), BaudRate115200);
    //ui->serial_BaudComboBox->setEditable(true);
    ui->serial_BaudComboBox->setCurrentIndex(8);
    connect(ui->serial_BaudComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(on_serial_BaudComboBox_currentIndexChanged(int)));
}

void main_frame::on_serial_BaudComboBox_currentIndexChanged(int index)
{
    if(index==0) // 如果当前选中的是第一项 "自定义"
    {
        ui->serial_BaudComboBox->setEditable(true); // 设置可编辑
        ui->serial_BaudComboBox->setItemText(index,tr("")); // 将第一项文本设为空
    }
    else // 如果当前选中的不是第一项 "自定义"
    {
        ui->serial_BaudComboBox->setEditable(false); // 设置不可编辑
        ui->serial_BaudComboBox->setItemText(0,tr("自定义")); // 将第一项文本设为 "自定义"
    }
}

2.2.2 代码分析

这段代码实现了串口波特率的设置和显示,具体解释如下:
首先在串口波特率的下拉框中添加各个波特率的选项,使用addItem()函数添加。其中第一个参数为字符串类型的波特率名称,第二个参数为整型的波特率数值。在此函数中还添加了一个自定义波特率的选项,对应的波特率数值为一个自定义的枚举类型BaudRateCustom
使用setEditable()函数设置下拉框可以编辑,但是这段代码中被注释掉了。
使用setCurrentIndex()函数设置当前显示的波特率为115200。
使用connect()函数连接波特率下拉框的currentIndexChanged()信号和主界面的on_serial_BaudComboBox_currentIndexChanged()槽函数,以实现在波特率改变时执行对应的操作。
槽函数 on_serial_BaudComboBox_currentIndexChanged,当 ui->serial_BaudComboBox 的当前选中项发生改变时会自动调用。该函数的作用是判断当前选中项是否为 “自定义”,如果是,则设置 ui->serial_BaudComboBox 为可编辑状态,并将第一项文本设为空;如果不是,则将 ui->serial_BaudComboBox 设为不可编辑状态,并将第一项文本设为 “自定义”。
总体来说,这段代码实现了串口波特率的显示和设置功能,并且对于自定义波特率也进行了处理。

2.2.3 运行效果图

2.3 数据位

2.3.1 代码设计

void main_frame::serialDataBits(void)
{
//    QStringList dataBitsList;
//    dataBitsList << "5" << "6" << "7" << "8";
//    ui->serial_dataBitscomboBox->addItems(dataBitsList);
//    ui->serial_dataBitscomboBox->setCurrentIndex(3);
    ui->serial_dataBitscomboBox->addItem(QStringLiteral("5"), QSerialPort::Data5);
    ui->serial_dataBitscomboBox->addItem(QStringLiteral("6"), QSerialPort::Data6);
    ui->serial_dataBitscomboBox->addItem(QStringLiteral("7"), QSerialPort::Data7);
    ui->serial_dataBitscomboBox->addItem(QStringLiteral("8"), QSerialPort::Data8);
    ui->serial_dataBitscomboBox->setCurrentIndex(3);  // 默认选中8位数据位
}

2.3.2 代码分析

这段代码是一个在QT的主窗口类(main_frame)中的函数,用于设置串口的数据位(data bits)的下拉菜单(QComboBox)。下面是每一行代码的作用:
第1行:定义了一个函数,函数名为serialDataBits。
第3-7行:通过addItem函数将数据位(data bits)选项添加到QComboBox中,参数1为显示的字符串,参数2为对应的数据位枚举值。
第8行:设置QComboBox默认选中的选项,这里默认选中8位数据位。

2.3.3 运行图

2.4 停止位

2.4.1 代码设计

void main_frame::serialStopBits(void)
{
    // 初始化停止位列表
//    QStringList stopBitsList;
//    stopBitsList << "1" << "1.5" << "2";
//    ui->serial_stopBitsComboBox->addItems(stopBitsList);
//    ui->serial_stopBitsComboBox->setCurrentIndex(0);
    // 设置停止位
    ui->serial_stopBitsComboBox->addItem("1", QSerialPort::OneStop);
    ui->serial_stopBitsComboBox->addItem("1.5", QSerialPort::OneAndHalfStop);
    ui->serial_stopBitsComboBox->addItem("2", QSerialPort::TwoStop);
}

2.4.2 代码分析

这段代码是为QComboBox添加串口停止位的选项,其中第一个参数是显示的文本,第二个参数是对应的枚举值,用于设置串口的停止位。这里分别添加了“1”、“1.5”、“2”三种选择,对应了QSerialPort::OneStop、QSerialPort::OneAndHalfStop、QSerialPort::TwoStop三个枚举值,分别表示1位停止位、1.5位停止位和2位停止位。用户选择对应选项后,可以通过QComboBox::currentData()函数获取该选项对应的枚举值,用于设置串口的停止位。

2.4.3 运行图

2.5 校验位

2.5.1 代码设计

void main_frame::serialParityBits(void)
{
    // 添加校验位选项
    ui->serial_parityBitscomboBox->addItem(QStringLiteral("无校验"), QSerialPort::NoParity);
    ui->serial_parityBitscomboBox->addItem(QStringLiteral("奇校验"), QSerialPort::OddParity);
    ui->serial_parityBitscomboBox->addItem(QStringLiteral("偶校验"), QSerialPort::EvenParity);
    ui->serial_parityBitscomboBox->addItem(QStringLiteral("标志"), QSerialPort::MarkParity);
    ui->serial_parityBitscomboBox->addItem(QStringLiteral("空格"), QSerialPort::SpaceParity);

}

2.5.2 代码分析

这段代码是一个函数,名为serialParityBits,主要是用来添加串口校验位的选项。

具体来说,它使用了Qt中的QComboBox控件,并且添加了五个不同的校验位选项。这些选项分别是“无校验”(NoParity)、“奇校验”(OddParity)、“偶校验”(EvenParity)、“标志”(MarkParity)和“空格”(SpaceParity)。每个选项都有一个相应的枚举值,用于在后续的串口设置中进行标识。

2.5.3 运行图

2.6 流控制

2.6.1 代码设计

 void main_frame::serialFlowControl(void)
{

// 添加流控制选项
    ui->serial_flowcomboBox->addItem(tr("None"), QSerialPort::NoFlowControl);
    ui->serial_flowcomboBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
    ui->serial_flowcomboBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
}

2.6.2 代码分析

这段代码是在串口设置界面中添加串口流控制选项。函数名为serialFlowControl,在该函数中,使用addItem函数添加了三个选项,分别为“None”(无流控制)、“RTS/CTS”(硬件流控制)和“XON/XOFF”(软件流控制),并分别对应了三个不同的枚举值,即QSerialPort::NoFlowControl、QSerialPort::HardwareControl和QSerialPort::SoftwareControl。

2.6.3 运行图

3 打开串口

3.1代码设计

void main_frame::on_serial_openPushButton_clicked(bool checked)
{
    if (checked)
    {
        // 设置要打开的串口的名字
        serialPort->setPortName(ui->serial_numcomboBox->currentData().toString());
        serialPort->setBaudRate(ui->serial_BaudComboBox->currentText().toInt());
        serialPort->setDataBits(static_cast<QSerialPort::DataBits>(ui->serial_dataBitscomboBox->currentData().toInt()));
        serialPort->setStopBits(static_cast<QSerialPort::StopBits>(ui->serial_stopBitsComboBox->currentData().toInt()));
        //serialPort->setStopBits(ui->serial_stopBitsComboBox->currentData().value<QSerialPort::StopBits>());
        serialPort->setParity(static_cast<QSerialPort::Parity>(ui->serial_parityBitscomboBox->currentData().toInt()));
        serialPort->setFlowControl(static_cast<QSerialPort::FlowControl>(ui->serial_flowcomboBox->currentData().toInt()));
 
        if (!serialPort->open(QIODevice::ReadWrite))
        {
            QMessageBox::about(this, "错误", "串口打开失败");
            QFont *font= new QFont;
            font->setPointSize(12);
            return;
        }
        else
        {
            ui->serial_openPushButton->setText("关闭串口");
            qDebug()<<"串口打开成功"<<serialPort->portName()<<"\n\r"
                    <<"波特率" << serialPort->baudRate()<<"\n\r"
                    <<"数据位" <<serialPort->dataBits()<<"\n\r"
                    <<"停止位" <<serialPort->stopBits()<<"\n\r"
                    <<"校验位"<<serialPort->parity()<<"\n\r"
                    <<"流控制" <<serialPort->flowControl()<<"\n\r";
        serialChangeEnble(true);

        }

    }
    else
    {
        // 关闭串口
        serialPort->close();

        ui->serial_openPushButton->setText("打开串口");
        serialChangeEnble(false);
    }
}

3.2 代码分析

这是一个串口通信程序中的槽函数,实现了打开/关闭串口、发送数据和接收数据的功能。

on_serial_openPushButton_clicked()函数是打开/关闭串口的槽函数,它在接收到按钮的点击信号时被调用。在函数中,首先获取用户在界面上设置的串口参数(如串口号、波特率、数据位、停止位、校验位和流控制等),然后通过串口对象设置这些参数。如果串口打开失败,弹出错误提示窗口;如果打开成功,则修改按钮的文本为“关闭串口”,并将串口参数显示在调试窗口中。

on_sendpushButton_clicked()函数是发送数据的槽函数,它在接收到发送按钮的点击信号时被调用。在函数中,首先将用户在界面上输入的数据转换为QByteArray类型,然后通过串口对象的write()函数发送数据。最后将发送的数据显示在界面的接收框中。

readSerial()函数是接收数据的槽函数,它在接收到串口对象的readyRead()信号时被调用。在函数中,首先通过串口对象的readAll()函数读取所有可用的数据,然后判断接收框中数据的长度是否超过了100000个字符,如果超过了就清空接收框。接着将读取的数据显示在界面的接收框中,同时将其输出到调试窗口中。注意,在接收和发送数据时要注意编码格式的问题,为了防止乱码问题,应该设计一个编码转换的问题。

总体来说,这个代码实现了基本的串口通信功能,通过界面的控件可以方便地设置串口参数和发送数据,同时也可以实时地接收串口返回的数据。

3.3 运行


注意:如果串口号字符和setPortName中的不一致,会导致串口打不开或者闪退现象。

4-接收区

4.1 清空接收区

void main_frame::on_clearReceivepushButton_clicked()
{
    ui->receivetextEdit->clear();
    qDebug()<<"清空接收区";
}

5 发送区

5.1 清空发送区

void main_frame::on_clearSendpushButton_clicked()
{
    ui->sendtextEdit->clear();
     qDebug()<<"清空发送区";
}

6 数据的发送和接收

void main_frame::on_sendpushButton_clicked()
{
     /*注意在编写接收和发送时一定要注意编码格式的问题,编码不对会导致乱码的问题,
      * 为了防止这个问题的出现,应该设计一个编码转换的问题*/
     QByteArray data = ui->sendtextEdit->toPlainText().toUtf8();

     serialPort->write(data);

     ui->receivetextEdit->append(tr("发送数据:") + QString(data)+"\n");


}
void main_frame::readSerial()
{

      QByteArray data = serialPort->readAll();
      if(ui->receivetextEdit->toPlainText().length()>100000)
      {
        ui->receivetextEdit->clear();
      }
      ui->receivetextEdit->moveCursor(QTextCursor::End);
      //ui->receivetextEdit->append(tr("接收数据:") + QString(data));

      ui->receivetextEdit->insertPlainText(tr("接收数据<--: ")+QString::fromUtf8(data));
      ui->receivetextEdit->insertPlainText("\n");  // 插入换行
      ui->receivetextEdit->moveCursor(QTextCursor::End);

      QThread::msleep(10); // 线程暂停10毫秒,以防止读取数据过快
    // ui->receivetextEdit->append(tr("接收数据:") + QString(data));
     qDebug()<<QString(data);

}

6.1代码分析

这是一个串口通信程序中的两个函数。第一个函数on_sendpushButton_clicked()是用来发送数据的,它将文本编辑框sendtextEdit中的文本转化为UTF-8编码的字节数组,并使用serialPort->write(data)函数将字节数组写入串口,同时在文本编辑框receivetextEdit中显示发送的数据。

第二个函数readSerial()是用来接收数据的。它使用serialPort->readAll()函数读取串口中的所有数据,并将数据显示在文本编辑框receivetextEdit中。同时,该函数在文本编辑框中插入了一个换行符,并暂停了10毫秒的时间,以防止读取数据过快导致程序崩溃。在这个函数中,也可以使用qDebug()函数将接收到的数据输出到控制台,方便调试。

7实际运行

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

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

相关文章

TCP协议策略

TCP可靠性 基于序号的确认应答(ACK)机制 TCP保证可靠性最核心的机制就是基于序号的确认应答机制。 TCP并不是百分之百可靠的&#xff0c;但是只要一条消息有应答&#xff0c;那么我们就可以确定该消息100%被对方收到了&#xff0c;这就是确认应答的意义。 可靠性不仅仅是保…

MOSS模型量化版部署过程

文章目录 项目背景配置环境与准备部署推理命令行部署报错1报错2&#xff1a; 网页版部署 项目背景 2023年4月21日&#xff0c;复旦大学自然语言处理实验室正式开放MOSS模型&#xff0c;是国内首个插件增强的开源对话大语言模型。MOSS 相关代码、数据、模型参数已在 GitHub 和 …

【键入网址到网页显示】

HTTP 对 URL 进行解析之后&#xff0c;浏览器确定了 Web 服务器和文件名&#xff0c;接下来就是根据这些信息来生成 HTTP 请求消息了。 http://www.server.com/dir1/file1.html http:访问数据的协议 www.server.com:服务器 dir1:目录名 file1.html:文件名生产 HTTP 请求信息…

SpringCloud-10_Alibaba Nacos

SpringCloud系列 SpringCloud-9、SleuthZipkin SpringCloud-8、Gateway网关服务 SpringCloud-7_OpenFeign服务调用 SpringCloud-6_Ribbon负载均衡 SpringCloud-5_模块集群化 文章目录 SpringCloud系列Nacos基础Nacos是什么&#xff1f;Nacos下载&运行 创建Nacos服务提供者…

JavaScript:哈希表

文章目录 哈希表242. 有效的字母异位词思路补充&#xff1a;JavaScript String charCodeAt() 方法代码详细分析 349. 两个数组的交集代码分析补充&#xff1a;JavaScript Set 对象思考一下哈希是什么&#xff1f;什么时候使用&#xff1f;补充&#xff1a;js 数组 map() 基本用…

github使用workflow工作流git push后自动打包部署github pages

workflows介绍 根目录新建.github/workflows/docs.yml .github/workflows/ 目录是用于存放 GitHub Actions 工作流程文件的目录&#xff0c;该目录的文件名必须以 .yml 或 .yaml 为后缀名&#xff0c;否则 GitHub 将无法识别该文件为工作流程文件。这些工作流程文件可用于自动…

速锐得基于能源油气生产智能监控的物联网应用

自2016年速锐得基于商用车国六环保排放监控管理开发以来&#xff0c;我们同时也接触了很多涉及商用车领域的深入项目&#xff0c;包括了大庆油田、山东能源、兖矿集团、陕北矿业等多家能源巨头在数字化、科技、无线远程控制、监控管理、生产效能等方面的智能化方向的趋势。 就目…

MySQL 字段为 NULL 的5大坑,大部分人踩过

数据库字段允许空值(null)的问题&#xff0c;小伙伴你遇到过吗&#xff1f; 在验证问题之前&#xff0c;我们先建一张测试表及测试数据。 构建的测试数据&#xff0c;如下图所示&#xff1a; 有了上面的表及数据之后&#xff0c;我们就来看当列中存在 NULL 值时&#xff0c;究…

基于RGB-D的6D目标检测算法

基于RGB-D的6D目标检测算法 本文参考了ITAIC的文章 A Review of 6D Object Pose Estimation 概览 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQX8ke6j-1683188966051)(https://mezereon-upic.oss-cn-shanghai.aliyuncs.com/uPic/image-20230420…

如何理解信息化、数字化和智能化的概念?一文给你解惑!

如何理解信息化、数字化和智能化的概念&#xff1f; 前两年流行“信息化”&#xff0c;网上铺天盖地都是关于“信息化”的文章&#xff0c;这两年开始流行起“数字化”&#xff0c;于是铺天盖地都是“数字化”的文章&#xff0c;最近又开始大谈“智能化”...... 但点开那些文…

常见的5种项目管理问题类型

项目管理的5大影响素&#xff1a;时间、范围、成本、风险、质量。项目经理需要对这些因素进行均衡考量&#xff0c;并根据需要略有侧重&#xff0c;进行整体把握&#xff0c;即我们常说的均衡型管理风格。而忽略任何一因素&#xff0c;都会对项目产生极大影响。 常见的项目管理…

医院导诊图怎么做?目前比较好用的医院导航地图是哪一款?

现在很多的大医院&#xff0c;不只是越建越高&#xff0c;面积也越来越大&#xff0c;同时医院内部按照门诊、住院、放射等不同功能划分的区域也是越来越多&#xff0c;走进这些“超级医院”就像走进了迷宫一样&#xff0c;如何促使病患走进医院后&#xff0c;能迅速找到要去的…

19C RAC主库 to RAC备库搭建adg报错ORA-16047(修改19C RAC DB_UNIQUE_NAME )

文章目录 前言一、问题描述二、修改DB_UNIQUE_NAME1.查看集群配置2.将hip40实例从集群中移除3.修改db_unique_name4.将hip40dg实例添加到集群资源中5.重新启动实例 三、19C RAC 密码文件替换 前言 主库环境是19C RAC备库环境也是19C RAC&#xff0c;主库到备库做adg&#xff0…

移动端动态开发能力的由来和流派

移动端动态化的由来 “动态化”并不是最近几年才产生的名词&#xff0c;而是从从互联网诞生的初期&#xff0c;这个词就已经出现了。大家所认知的早期互联网&#xff0c;其实就是各种各类的“动态网站”&#xff0c;内容数据和页面外观都不是固定的&#xff0c;都是随着服务器…

Bash脚本中的Sleep命令到底有何妙用?

在编写Bash脚本时&#xff0c;有时需要在程序执行过程中加入一些等待时间&#xff0c;例如等待某个操作完成或等待某个进程退出。此时可以使用sleep命令来实现。 sleep命令可以让脚本暂停执行一段时间&#xff0c;其基本语法为&#xff1a; sleep <seconds>其中&#xf…

细数【SD-WEBUI】的模型:谁是最适合的模型从哪里找到它们

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;基础模型&#xff08;Stable-Diffusion模型&#xff09;&#xff08;1.1&#xff09;ChilloutMix&#xff08;仿真&#xff09;&#xff08;1.2&#xff09;BasilMix&#xff08;仿真&#xff09;&#xff0…

如何使用 Linux Cron Job 优化WP-Cron以获得更好的性能

在本教程中&#xff0c;我将向您展示如何通过在 Linux 上用 Crontab 替换默认的 WP-Cron 触发机制来优化 WordPress 性能。 WordPress 使用 WP-Cron 来运行计划任务&#xff0c;许多用户已经在使用。 但它的工作方式并不理想。 在每次页面加载时&#xff0c;WP-Cron 检查计划…

在Centos7上安装和配置canal

1. 在 MySQL 数据库中创建 Canal 账户并为其授权 在安装 Canal 前&#xff0c;你需要在 MySQL 数据库中创建一个用于 Canal 连接的账户&#xff0c;并为该账户授予必要的权限。 以下是在 MySQL 数据库中创建 Canal 账户并为其授权的步骤&#xff1a; 登录 MySQL 使用以下命令…

B019_子查询篇

2022-4-30 18:11:32 通过本章学习,您将可以: 描述子查询可以解决的问题。 定义子查询。 列出子查询的类型。 书写单行子查询和多行子查询 MEGER INTO的使用 WITH 子句🏆CHAPTER 12 Subqueries & Merge Statements子查询和合并语句 子查询——嵌套在另一个查询中的查…

MyBatis:使用代码整合

文章目录 MyBatis&#xff1a;Day 04框架1. 依赖&#xff1a;pom.xml2. 外部配置文件&#xff1a;db.properties3. 核心配置文件&#xff1a;mybatis-config.xml4. 实体类5. 接口&#xff1a;xxxMapper.java6. 实现类&#xff1a;xxxMapper.xml7. 测试 MyBatis&#xff1a;Day …