Qt实现串口助手

 更新时间:2022年08月19日 11:07:10   作者:林子xxx  
这篇文章主要为大家详细介绍了Qt实现串口助手,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Qt实现串口助手的具体代码,供大家参考,具体内容如下

1.界面布局

这是一个常见的串口助手布局。要说有什么不常见,大概就是发送可以选择编码方式:GBK/UTF8

2.要点

没什么难度,就是水磨工夫,一点点写。容易错处的地方都写在代码注释里。

3.代码

下面是 mainwindow.cpp 文件。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qdebug.h>
 
QSerialPort *serial;
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    serial = new QSerialPort;
 
    findSerialPort();
 
    ui->cbbBaudrate->addItem(QStringLiteral("4800"), QSerialPort::Baud4800);
    ui->cbbBaudrate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
    ui->cbbBaudrate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
    ui->cbbBaudrate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
    ui->cbbBaudrate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
    ui->cbbBaudrate->setCurrentIndex(4);
    //添加数据位
     ui->cbbDataSize->addItem(QStringLiteral("5"), QSerialPort::Data5);
     ui->cbbDataSize->addItem(QStringLiteral("6"), QSerialPort::Data6);
     ui->cbbDataSize->addItem(QStringLiteral("7"), QSerialPort::Data7);
     ui->cbbDataSize->addItem(QStringLiteral("8"), QSerialPort::Data8);
     ui->cbbDataSize->setCurrentIndex(3);
     //添加奇偶校验位
     ui->cbbParity->addItem(tr("None"), QSerialPort::NoParity);
     ui->cbbParity->addItem(tr("Even"), QSerialPort::EvenParity);
     ui->cbbParity->addItem(tr("Odd"), QSerialPort::OddParity);
     ui->cbbParity->addItem(tr("Mark"), QSerialPort::MarkParity);
     ui->cbbParity->addItem(tr("Space"), QSerialPort::SpaceParity);
     ui->cbbParity->setCurrentIndex(0);
     //添加停止位
     ui->cbbStopbit->addItem(QStringLiteral("1"), QSerialPort::OneStop);
     ui->cbbStopbit->addItem(QStringLiteral("1.5"), QSerialPort::OneAndHalfStop);//
     ui->cbbStopbit->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
     ui->cbbStopbit->setCurrentIndex(0);
     //添加流控位
     ui->cbbFlowbit->addItem(tr("None"), QSerialPort::NoFlowControl);
     ui->cbbFlowbit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
     ui->cbbFlowbit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
     ui->cbbFlowbit->setCurrentIndex(0);
     //禁用发送按钮
     ui->btnSend->setEnabled(false);
 
     ui->btnOpen->setStatusTip(tr("打开/关闭串口"));
     ui->rdbGbk->setStatusTip("以GBK编码发送" );
     ui->rdbUtf8->setStatusTip(tr("以UTF8编码发送"));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::findSerialPort()
{
    ui->cbbPort->clear();
    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        QSerialPort tempserial;
        tempserial.setPort(info);
 
        if(tempserial.open(QIODevice::ReadWrite))
        {
            ui->cbbPort->addItem(info.description()+":"+tempserial.portName(),tempserial.portName());
 
            tempserial.close();
        }
    }
}
 
void MainWindow::setsuienable( bool en )
{
    ui->cbbPort->setEnabled(en);
    ui->cbbBaudrate->setEnabled(en);
    ui->cbbDataSize->setEnabled(en);
    ui->cbbParity->setEnabled(en);
    ui->cbbStopbit->setEnabled(en);
    ui->cbbFlowbit->setEnabled(en);
}
 
void MainWindow::on_btnOpen_clicked()
{
    if(ui->btnOpen->text()  != "关闭")
    {
        if( !ui->cbbPort->currentText().isNull() )
        {
 
            ui->btnOpen->setText("关闭");
            ui->btnSend->setEnabled(true);
            ui->btnFind->setEnabled(false);
            setsuienable(false);
 
            serial->setPortName(ui->cbbPort->currentData(Qt::UserRole).value<QString>()  );
            serial->setBaudRate(ui->cbbBaudrate->currentData(Qt::UserRole).value<qint32>() );
            serial->setDataBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::DataBits>() );
            serial->setFlowControl(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::FlowControl>() );
            serial->setParity(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::Parity>() );
            serial->setStopBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::StopBits>() );
            serial->open(QIODevice::ReadWrite);
 
 
            connect(serial, &QSerialPort::readyRead, this, &MainWindow::serialReadData);
        }
    }
    else
    {
        serial->close();
        setsuienable(true);
        ui->btnSend->setEnabled(false);
        ui->btnOpen->setText("打开");
        ui->btnFind->setEnabled(true);
    }
}
 
//字符串数据转为HEX,16进制形式。譬如将 “30”转为“0”
bool StringToHex( QString &dst,const QString src )
{
    QStringList list = src.trimmed().split(QRegExp("\t|\n|\r\n|\r| |,|;")); //去除头尾空白,再分割
 
    foreach (QString n,  list )
    {
        bool res;
        if(n.isEmpty())continue;
        int d= n.toInt(&res,16);
        if(d>255){  return  false ;}
 
        char  c = d;
        if(res)
            dst.append(c);
        else
            return  false ;
    }
    return true;
}
//UTF8转为GBK
QByteArray Utf8ToGbk(QByteArray buf)
{
    QTextCodec* Utf8Codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(Utf8Codec);
    QTextCodec* GbkCodec = QTextCodec::codecForName("GBK");
 
    QByteArray ByteGbk = GbkCodec->fromUnicode( Utf8Codec->toUnicode( buf ) );   //先Unicode编码,后arr
 
    return  ByteGbk ;
}
//串口发送
void MainWindow::on_btnSend_clicked()
{
    if( ui->teSend->toPlainText() .isEmpty() )return;
 
    if( ui->ckbSendhex->isChecked()  )
    {
        QString txt;
        if( StringToHex( txt ,ui->teSend->toPlainText() ) )
        {
            serial->write( txt.toLatin1()  );
        }else
        {
            QMessageBox::about(this,tr("提示"),tr("HEX数据格式错误,\n数据形式类似:30 34 56"));
        }
    }
    else{
        if( ui->rdbUtf8->isChecked() )
        {
            serial->write( ui->teSend->toPlainText().toUtf8()   );
        }else
        {
            QByteArray arrutf8 =ui->teSend->toPlainText().toLocal8Bit();
            serial->write( Utf8ToGbk(arrutf8)   );
        }
    }
}
 
//串口接收处理
void MainWindow::serialReadData()
{
   //注意,直接append会从下一行开始,所以先放入QString
    QByteArray buf = serial->readAll();
    if(!buf.isEmpty())
    {
        QString txt = ui->teReceive->toPlainText();
 
        if( ui->ckbReceivehex->isChecked() )
        {
            ui->teReceive->append( QString( buf.toHex(' ') ) );
        }
        else
        {
            QTextCodec::ConverterState state;
            QTextCodec *codec = QTextCodec::codecForName("UTF-8");
            QString str = codec->toUnicode( buf.constData(), buf.size(), &state);
            if ( state.invalidChars )
            {
               str = QTextCodec::codecForName( "GBK" )->toUnicode(buf);
            }
            else
            {
               str =  codec->toUnicode(buf);
            }
            ui->teReceive->clear();
            ui->teReceive->append(  txt+str  );
        }
    }
 
}
 
void MainWindow::on_btnClearReceive_clicked()
{
    ui->teReceive->clear();
}
 
void MainWindow::on_btnClearSend_clicked()
{
    ui->teSend->clear();
}
 
void MainWindow::on_btnFind_clicked()
{
    ui->btnFind->setEnabled(false);
    findSerialPort();
    ui->btnFind->setEnabled(true);
}

4.效果

测试可以发送和接收GK/UTF8编码的数据。下图是和ATK-XCOM通过虚拟串口交互。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解C++ 引用

    详解C++ 引用

    这篇文章主要介绍了C++ 引用的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C++ Boost Spirit入门教程

    C++ Boost Spirit入门教程

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C++ 中boost::share_ptr智能指针的使用方法

    C++ 中boost::share_ptr智能指针的使用方法

    这篇文章主要介绍了C++ 中boost::share_ptr智能指针的使用方法的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-10-10
  • C语言数据结构单链表接口函数全面讲解教程

    C语言数据结构单链表接口函数全面讲解教程

    这篇文章主要为大家介绍了C语言数据结构单链表所有接口函数的全面讲解教程,有需要朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-10-10
  • C++中 string 中的常用方法使用心得

    C++中 string 中的常用方法使用心得

    这篇文章主要介绍了C++中 string 中的常用方法使用心得,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C语言中的strncpy()函数的用法及应用场景详解

    C语言中的strncpy()函数的用法及应用场景详解

    在C语言编程中,strncpy函数用于安全地复制字符串,它可以指定复制的字符数以防止缓冲区溢出,这篇文章主要介绍了C语言中的strncpy()函数的用法及应用场景的相关资料,并提供了示例代码,需要的朋友可以参考下
    2024-10-10
  • c++11 新特性——智能指针使用详解

    c++11 新特性——智能指针使用详解

    这篇文章主要介绍了c++11 新特性——智能指针使用的相关资料,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下
    2021-02-02
  • C++中的类型查询之探索typeid和type_info(推荐)

    C++中的类型查询之探索typeid和type_info(推荐)

    C++ 是一种静态类型语言,这意味着每个变量的类型在编译时就已经确定,在这篇技术分享中,我们将探讨 C++ 中的 typeid 和 type_info,以及如何使用它们来获取类型信息,需要的朋友可以参考下
    2024-05-05
  • C++ COM编程之什么是接口?

    C++ COM编程之什么是接口?

    这篇文章主要介绍了C++ COM编程之什么是接口?在C++中,可以使用抽象基类来实现COM接口,需要的朋友可以参考下
    2014-10-10
  • C语言之从字符数组中删除特定的字符

    C语言之从字符数组中删除特定的字符

    本篇文章主要介绍了从字符数组中删除特定字符的实现方法,有需要的朋友可以参考下
    2015-07-07

最新评论