【QT】串口助手(优化升级)

目录

1、成品展示

1.1 电脑PC端展示

1.2 嵌入式ARM端展示

2、程序代码

2.1 程序框架

2.2 serial.pro

2.3 serial.ui

2.4 serial.h

2.5 serial.cpp 

2.6 main.cpp

3、源代码下载链接



1、成品展示

1.1 电脑PC端展示

1.2 嵌入式ARM端展示

2、程序代码

2.1 程序框架

2.2 serial.pro

QT       += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    serial.cpp

HEADERS += \
    serial.h

FORMS += \
    serial.ui

RC_ICONS = system.ico

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    res.qrc

2.3 serial.ui

2.4 serial.h

#ifndef SERIAL_H
#define SERIAL_H

#include <QMainWindow>

/*-------------user-------------------*/
/*---port--*/
#include <QSerialPort>
#include <QSerialPortInfo>
/*---QString--*/
#include <QString>
/*---QDateTime--*/
#include <QDateTime>
/*---QTimer--*/
#include <QTimer>
/**/
#include <QFile>
#include <QFileDialog>
/**/
#include <QToolBar>
/*---QDebug--*/
#include <QDebug>
#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"
/* -----------------------------------*/

QT_BEGIN_NAMESPACE
namespace Ui { class Serial; }
QT_END_NAMESPACE

class Serial : public QMainWindow
{
    Q_OBJECT

public:
    Serial(QWidget *parent = nullptr);
    ~Serial();

signals:    //自定义信号
    //发送使能信号
    void my_send_signals(bool);

private slots:  //自定义槽函数
    //检测通讯端口槽函数
    void btn_serial_check(bool);
    //打开选择端口槽函数
    void btn_open_port(bool);
    //关闭选择端口槽函数
    void btn_close_port(bool);
    //发送数据槽函数
    void btn_send_data(bool);
    //接收数据槽函数
    void receive_data(void);
    //清空接收槽函数
    void btn_clear_rev(bool);

    //自动发送复选框槽函数
    void on_checkBox_stateChanged(int arg1);

    //打开发送文件槽函数
    void btn_open_send_file(bool);
    //保存接收日志槽函数
    void btn_save_rev_log(bool);

    //清空发送槽函数
    void btn_clear_send(bool);

private:
    Ui::Serial *ui;
    /*--------funtion---------------------*/
    //用户系统初始化
    void system_init();
    //字符串转16进制
    QByteArray QString2Hex(QString str);
    //字符转16进制
    char ConvertHexChar(char ch);
    /*--------variable--------------------*/
    //串口全局类声明
    QSerialPort global_port;
    //自动发送定时器声明
    QTimer *timer;
};
#endif // SERIAL_H

2.5 serial.cpp 

#include "serial.h"
#include "ui_serial.h"

Serial::Serial(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Serial)
{
    ui->setupUi(this);

    /*----------user-----------*/
    //init 用户系统初始化
    system_init();
}

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

/*---------------------------------------------------------------------
 *             funtion
 * --------------------------------------------------------------------*/
//用户系统初始化
void Serial::system_init()
{
    //port conifg
    ui->cmd_port_name->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        //将可用串口添加到端口显示框
        ui->cmd_port_name->addItem(info.portName());
    }

    //设置串口状态标签为红色 表示未连接状态
    ui->lab_status->setStyleSheet("color:red");
    //statusBar 状态栏显示端口状态 未连接
    QString sm = "%1 CLOSED";
    QString status = sm.arg(ui->cmd_port_name->currentText());
    ui->statusBar->showMessage(status);
    ui->statusBar->setStyleSheet("color:red");

    //timer 自动发送
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,[=](){
        emit my_send_signals(true); //触发发送信号
    });

    QToolBar *toolBar = addToolBar("toolBar");
    QPushButton *btn_check = new QPushButton("检测串口",this);
    QPushButton *btn_open = new QPushButton("打开串口",this);
    QPushButton *btn_close = new QPushButton("关闭串口",this);
    QPushButton *btn_clear = new QPushButton("清空接收",this);
    QPushButton *btn_file = new QPushButton("打开文件",this);
    QPushButton *btn_log = new QPushButton("保存日志",this);
    toolBar->addWidget(btn_check);
    toolBar->addWidget(btn_open);
    toolBar->addWidget(btn_close);
    toolBar->addWidget(btn_clear);
    toolBar->addWidget(btn_file);
    toolBar->addWidget(btn_log);

    //connect
    //check port 检测通讯端口
    connect(btn_check,&QPushButton::clicked,this,&Serial::btn_serial_check);
    //open port 打开选择端口
    connect(btn_open,&QPushButton::clicked,this,&Serial::btn_open_port);
    //close port 关闭选择端口
    connect(btn_close,&QPushButton::clicked,this,&Serial::btn_close_port);
    //clear recevie 清除接收文本框的内容
    connect(btn_clear,&QPushButton::clicked,this,&Serial::btn_clear_rev);
    //打开发送文件
    connect(btn_file,&QPushButton::clicked,this,&Serial::btn_open_send_file);
    //保存接收日志
    connect(btn_log,&QPushButton::clicked,this,&Serial::btn_save_rev_log);

    //send data 发送按钮 触发发送信号
    connect(ui->btn_send,&QPushButton::clicked,[=](){
        emit my_send_signals(true);
    });
    //发送信号   发送槽函数
    connect(this,&Serial::my_send_signals,this,&Serial::btn_send_data);

    //receive data 串口数据接收完触发更新添加显示接收文本框
    connect(&global_port,&QSerialPort::readyRead,this,&Serial::receive_data);

    //clear recevie 清除发送文本框的内容
    connect(ui->btn_clear_send,&QPushButton::clicked,this,&Serial::btn_clear_send);
}

//字符串转16进制
QByteArray Serial::QString2Hex(QString str)
{
    QByteArray senddata;
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();

    senddata.resize(len/2);
    char lstr,hstr;

    for(int i=0; i<len; )
    {
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}
//字符转16进制
char Serial::ConvertHexChar(char ch)
{
    if((ch >= '0') && (ch <= '9'))
        return ch-0x30;
    else if((ch >= 'A') && (ch <= 'F'))
        return ch-'A'+10;
    else if((ch >= 'a') && (ch <= 'f'))
        return ch-'a'+10;
    else return (-1);
}

/*---------------------------------------------------------------------
 *             slots
 * --------------------------------------------------------------------*/
//检测通讯端口槽函数
void Serial::btn_serial_check(bool)
{
    ui->cmd_port_name->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->cmd_port_name->addItem(info.portName());
    }
}

//打开选择端口槽函数
void Serial::btn_open_port(bool)
{
    //port name 设置端口
    global_port.setPortName(ui->cmd_port_name->currentText());
    //baud rate 设置波特率
    global_port.setBaudRate(ui->cmd_baud_rate->currentText().toInt());
    //parity 设置校验位
    switch (ui->cmd_parity->currentIndex()) {
    case 0:     //无校验
        global_port.setParity(QSerialPort::NoParity);
        break;
    case 1:     //偶校验
        global_port.setParity(QSerialPort::EvenParity);
        break;
    default:    //奇校验
        global_port.setParity(QSerialPort::OddParity);
        break;
    }

    //data bits 设置数据位
    switch (ui->cmd_data_bits->currentText().toInt()) {
    case 8:
        global_port.setDataBits(QSerialPort::Data8);
        break;
    case 7:
        global_port.setDataBits(QSerialPort::Data7);
        break;
    case 6:
        global_port.setDataBits(QSerialPort::Data6);
        break;
    default:
        global_port.setDataBits(QSerialPort::Data5);
        break;
    }

    //stop bits 设置停止位
    switch (ui->cmd_stop_bits->currentIndex()) {
    case 0:
        global_port.setStopBits(QSerialPort::OneStop);
        break;
    case 1:
        global_port.setStopBits(QSerialPort::OneAndHalfStop);
        break;
    default:
        global_port.setStopBits(QSerialPort::TwoStop);
        break;
    }

    //port open 打开选择端口
    bool ret = global_port.open(QIODevice::ReadWrite);

    if(ret){
        //打开成功更新状态
        ui->lab_status->setText("OPENED");
        //设置串口状态标签为绿色 表示已连接状态
        ui->lab_status->setStyleSheet("color:green");

        //statusBar 状态栏显示端口状态
        QString sm = "%1 OPENED, %2, 8, NONE, 1";
        QString status = sm.arg(global_port.portName()).arg(global_port.baudRate());
        ui->statusBar->showMessage(status);
        ui->statusBar->setStyleSheet("color:green");
    }
}

//关闭选择端口槽函数
void Serial::btn_close_port(bool)
{

    global_port.close();

    //关闭端口后显示状态
    ui->lab_status->setText("CLOSED");
    ui->lab_status->setStyleSheet("color:red");

    //statusBar 状态栏显示端口状态
    QString sm = "%1 CLOSED";
    QString status = sm.arg(global_port.portName());
    ui->statusBar->showMessage(status);
    ui->statusBar->setStyleSheet("color:red");
}

//发送数据槽函数
void Serial::btn_send_data(bool)
{
    QString data = ui->pte_send->toPlainText();
    QByteArray array;

    //Hex复选框
    if(ui->chk_send_hex->checkState() == Qt::Checked){
        array = QString2Hex(data);  //HEX 16进制
    }else{
        array = data.toLatin1();    //ASCII
    }
    global_port.write(array);   //发送数据
}

//接收数据槽函数
void Serial::receive_data(void)
{
    QByteArray array = global_port.readAll();
    QString str_rev;

    if(ui->chk_rev_hex->checkState() == Qt::Checked){   //HEX 16进制
        if(ui->chk_rev_line->checkState() == Qt::Checked){  //自动换行
            if(ui->chk_rev_time->checkState() == Qt::Checked){  //显示时间
                //获取当前系统时间
                QDateTime nowtime = QDateTime::currentDateTime();
                //时间转换为字符串格式
                str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
                //加上接收数据 转换为16进制并空格分开 接收数据换行
                str_rev += QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");
            }else{
                str_rev = QString(array.toHex(' ').toUpper().append(' ')).append("\r\n");
            }
        }else{
            str_rev = QString(array.toHex(' ').toUpper().append(' '));
        }

    }else{
        if(ui->chk_rev_line->checkState() == Qt::Checked){
            if(ui->chk_rev_time->checkState() == Qt::Checked){
                QDateTime nowtime = QDateTime::currentDateTime();
                str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
                str_rev += QString(array).append("\r\n");
            }else{
                str_rev = QString(array).append("\r\n");
            }
        }else{
            str_rev = QString(array);
        }

    }

    //将光标定位到最后
    ui->tb_rev->moveCursor(QTextCursor::End);
    //文本框显示接收数据
    ui->tb_rev->insertPlainText(str_rev);

}

//清空接收文本框槽函数
void Serial::btn_clear_rev(bool)
{
    ui->tb_rev->clear();
}

//自动触发复选框  启动定时器和停止定时器
void Serial::on_checkBox_stateChanged(int arg1)
{
    if(arg1){
        timer->start(ui->spinBox->value()); //启动定时器
    }else{
        timer->stop();  //停止定时器
    }
}

//打开发送文件槽函数
void Serial::btn_open_send_file(bool)
{
    QString path = QFileDialog::getOpenFileName(this,"open","../","TXT(*.txt)");
    if(!path.isEmpty()){
        QFile file(path);
        bool isOk = file.open(QIODevice::ReadOnly);
        if(isOk){
            ui->pte_send->setPlainText(QString(file.readAll()));
        }
        file.close();
    }
}

//保存接收日志槽函数
void Serial::btn_save_rev_log(bool)
{
    QString path = QFileDialog::getSaveFileName(this,"save","../","TXT(*.txt)");
    if(!path.isEmpty()){
        QFile file(path);
        bool isOk = file.open(QIODevice::WriteOnly);
        if(isOk){
            file.write(ui->tb_rev->toPlainText().toStdString().data());
        }
        file.close();
    }
}

//清空发送槽函数
void Serial::btn_clear_send(bool)
{
    ui->pte_send->clear();
}

2.6 main.cpp

#include "serial.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Serial w;
    w.show();
    return a.exec();
}

3、源代码下载链接

【QT】串口助手(优化升级 详细注解) qt5_serial.zip 

https://download.csdn.net/download/hanhui22/14044219

 

 

  • 7
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: QT串口助手是一款基于QT开发的串口调试工具。它可以用于串口通信的功能测试、命令发送与接收等调试工作。 QT串口助手具有简单易用的特点。它提供了直观的用户界面,用户可以方便地设置串口的端口号、波特率、校验位等参数。用户可以通过界面上的发送按钮,发送指定的命令给目标设备,并实时查看接收数据。同时,QT串口助手还支持自定义命令的编辑,用户能够按照自己的需求定义需要发送的数据。 QT串口助手还具备实时监测串口数据的能力。在串口打开的状态下,它能够持续地监听串口接收的数据,并将其显示在界面的接收区域中。用户可以清楚地查看接收到的数据内容,帮助用户判断通信是否正常,并进行相应的调试。 此外,QT串口助手还支持十六进制显示功能。用户可以选择以十进制还是十六进制的形式查看接收和发送的数据。这对于一些需要进行十六进制数据处理的应用场景非常有帮助。 总之,QT串口助手是一款方便实用的串口调试工具。它能够为用户提供简单易用的操作界面,并具备实时监测数据、自定义命令等功能,为串口通信调试提供便利。 ### 回答2: Qt串口助手是一款功能强大的调试工具,用于帮助开发者在Qt开发环境下进行串口通信的调试工作。 首先,Qt串口助手提供了友好的用户界面,使得串口通信的设置和调试变得简单易用。它支持多种串口参数设置,如波特率、数据位、校验位和停止位等,用户可以根据需求灵活地设置串口参数。 其次,Qt串口助手支持发送和接收数据。用户可以在发送数据输入框中输入要发送的数据,点击发送按钮即可将数据发送到串口设备。同时,接收数据框会实时显示从串口设备接收到的数据,方便用户查看和分析。 另外,Qt串口助手还提供了数据发送和接收的统计功能,用户可以实时监测发送和接收的数据量,从而方便对数据进行分析和优化。 此外,Qt串口助手还支持自定义发送指令,用户可以通过输入要发送的指令以及相应的参数,进行自定义的指令发送。这对于特定的串口设备调试非常有用。 最后,Qt串口助手还支持串口设备的自动检测和连接,用户只需点击扫描按钮即可自动检测当前连接的串口设备,并进行连接。这极大地方便了用户在多个串口设备之间进行切换。 综上所述,Qt串口助手是一款强大且易用的串口调试工具,能够满足开发者在Qt开发环境下对串口通信进行调试的需求。 ### 回答3: Qt串口助手是一款用于调试串口通信的工具。在开发和调试串口通信相关的应用程序时,我们经常需要通过串口与外部设备进行数据的收发和交互。Qt串口助手提供了方便易用的界面和功能,帮助我们轻松地完成串口调试工作。 Qt串口助手的主要特点有: 1. 支持多种串口通信参数设置:包括波特率、数据位、校验位、停止位等,可根据实际需求进行配置。 2. 支持发送和接收功能:我们可以在发送区输入要发送的数据,并通过串口将数据发送出去;同时,在接收区可以实时显示收到的数据,方便我们进行及时观察和调试。 3. 支持ASCII和HEX两种数据表示方式:我们可以选择以ASCII字符或十六进制格式显示发送和接收的数据,便于不同需求下的数据解析和调试。 4. 支持自定义指令发送:我们可以预先定义一些常用的指令,在需要时快速选择并发送,提高调试效率。 5. 支持数据循环发送:我们可以设置数据的发送间隔时间和发送次数,实现连续发送指定数据,方便复杂场景下的调试。 Qt串口助手可以帮助我们快速而准确地获取串口通信的数据信息,方便我们进行串口通信开发和调试工作。不仅如此,Qt串口助手还具有非常友好的界面和操作方式,使得使用起来非常简单和方便。无论是初学者还是有经验的开发者,都能很好地利用该工具完成串口调试任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值