首先非常感谢CSDN吾爱技术圈分享的QT初体验:手把手带你写一个自己的串口助手,本教程重点参考
1. 前言
由于qt应用项目需求,前期也安装过QT(参考博客:【Qt安装与简易串口控制Arduino开发板小灯教程】),这次就好好来学习QT串口助手制作,该应用有基本串口设置和收发功能,可以深刻理解按键,数据交互的信号槽机制,不免有许多模块功能组件设计,最后还需要排版设计优化。本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程,整个工程只有几百行代码,跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法。最好每个功能自己都试试增加自信心!
💕💕💕
先来看看作品:
2. 制作过程
2.1. 布局UI界面
(1) 创建QMainWindow工程。这一步就不赘述了,参考:【Qt安装与简易串口控制Arduino开发板小灯教程】
创建项目时项目名称可以设为Serial,基类可以选择QMainWindow。注意默认勾选“Generate form”,生成 ui 窗体文件 mainwindow.ui 后面要用到。完成后项目文件展示:
(2)双击mainwindow.ui打开UI布局界面,从左侧控件选择区找到需要的控件拖动到界面设计区的对应位置
(请注意:以下提到的摆放位置只放大概位置即可,因为必须借用布局工具才能规正)
- 找到Label控件,用于显示:
用8个Lable控件分别按下图所示红框位置摆放,并且双击改显示的文字,或单击选择对应Lable后在其右边属性设置界面里的text属性更改
- 找到Combo Box控件:
用5个Combo Box控件分别按下图绿色框所示位置摆放
- 找到Push Button控件,按键事件触发:
用5个Push Button控件分别按下图紫色框所示位置摆放,并且双击按钮改显示的文字
- 找到Check Box控件,检查框设计模式配置属性:
用6个Check Box控件分别按下图蓝色框所示位置摆放,并且双击更改显示的文字
-
用1个Spin Box控件分别按下图棕色框所示位置摆放并调整大小
-
最后两个大的白色区域就是接收框和发送输入框,上面接收框用Plain Text Edit控件,下面输入框用Text Edit控件
接收框用的Plain Text Edit控件需要更改属性为只读
2.2 添加下拉列表项
5个Combo Box控件分别双击添加列表项(端口对应的Combo Box不用改)
波特率:
(点击绿色加号即可添加)
数据位:
停止位:
校验位:
对于波特率和数据位的下拉列表控件还需要通过更改属性currentIndex属性,改变默认值。波特率默认9600,数据位默认8。
2.3 修改控件名称
下面对控件进行改名,以便对应程序中的对象名,用默认名不直观。
如何改名?
点击控件,找到界面右边属性栏的objectName。
名称参考下图:
注意这一步一定要把对象名设置对,否则在编译程序时会有问题。不过建议大家根据自己的习惯命名,方便快速查找,下面会给出全部文件。
2.4. 利用布局工具
第一步放置控件的时候,想必就会发现根本很难通过鼠标拖动的方法完成对齐,这时还得用上方菜单栏的布局工具:
下图中的红框就是布局后才显示的:
操作方法是先手动把控件摆放到大概位置,然后鼠标左键拉一个框选定几个控件,再点击上面的布局工具。
接收设置和发送设置就是用了栅格布局,发送和清空发送按钮是垂直布局,串口设置中是上面部分是栅格布局,然后整体再用垂直布局。布局后的红框还可以调整大小。最后这4个框是Group Box控件,双击就可以改文字。为啥把这步放最后了是因为发现Group Box控件放上去后直接选不了里面的控件了,暂时不知道怎么操作。这里跟VS里不一样,VS就比较方便
3. 编写程序
main.cpp
不需要修改,双击打开.pro文件
core gui后面添加serialport,即 QT += core gui serialport
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
3.1 mainwindow.h文件源码:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QString>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QTimer>
#include <QTime>
#include <QPainter>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QSerialPort *serialPort;//定义串口指针
private slots:
// void on_button_openserial_clicked();
/*手动连接槽函数*/
void manual_serialPortReadyRead();
void on_chkTimSend_stateChanged(int arg1);
/*以下为mainwindow.ui文件中点击“转到槽”自动生成的函数*/
void on_Serial_check_Bt_clicked();
void on_open_serial_Bt_clicked();
void on_send_Bt_clicked();
void on_clear_recv_Bt_clicked();
void on_clear_send_Bt_clicked();
private:
Ui::MainWindow *ui;
// 发送、接收字节计数
long sendNum, recvNum;
QLabel *lblSendNum;
QLabel *lblRecvNum;
QLabel *lblPortState;
void setNumOnLabel(QLabel *lbl, QString strS, long num);
// 定时发送-定时器
QTimer *timSend;
};
#endif // MAINWINDOW_H
3.2 mainwindow.cpp文件源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QSerialPortInfo"
#include <QSerialPort>
#include <QMessageBox>
#include <QDateTime>
#include <QStatusBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList serialNamePort;
serialPort = new QSerialPort(this);
connect(serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手动连接槽函数*/
/*找出当前连接的串口并显示到serailCb*/
//foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
//{
//serialNamePort<<info.portName();// 自动扫描当前可用串口,返回值追加到字符数组中
//}
//ui->serailCb->addItems(serialNamePort);// 可用串口号,显示到串口选择下拉框中
ui->serial_Cb->clear();
//通过QSerialPortInfo查找可用串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
ui->serial_Cb->addItem(info.portName());
}
// 发送、接收计数清零
sendNum = 0;
recvNum = 0;
// 状态栏
QStatusBar *sBar = statusBar();
// 状态栏的收、发计数标签
lblSendNum = new QLabel(this);
lblRecvNum = new QLabel(this);
lblPortState = new QLabel(this);
lblPortState->setText("Connected");
//设置串口状态标签为绿色 表示已连接状态
lblPortState->setStyleSheet("color:red");
// 设置标签最小大小
lblSendNum->setMinimumSize(100, 20);
lblRecvNum->setMinimumSize(100, 20);
lblPortState->setMinimumSize(550, 20);
setNumOnLabel(lblSendNum, "S: ", sendNum);
setNumOnLabel(lblRecvNum, "R: ", recvNum);
// 从右往左依次添加
sBar->addPermanentWidget(lblPortState);
sBar->addPermanentWidget(lblSendNum);
sBar->addPermanentWidget(lblRecvNum);
// 定时发送-定时器
timSend = new QTimer;
timSend->setInterval(1000);// 设置默认定时时长1000ms
connect(timSend, &QTimer::timeout, this, [=](){
on_send_Bt_clicked();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_Serial_check_Bt_clicked()
{
ui->serial_Cb->clear();
//通过QSerialPortInfo查找可用串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
ui->serial_Cb->addItem(info.portName());
}
}
void MainWindow::on_open_serial_Bt_clicked()
{
/*串口初始化*/
QSerialPort::BaudRate baudRate;
QSerialPort::DataBits dataBits;
QSerialPort::StopBits stopBits;
QSerialPort::Parity checkBits;
// 获取串口波特率
// baudRate = ui->baundrate_Cb->currentText().toInt();直接字符串转换为 int 的方法
if(ui->baundrate_Cb->currentText()=="1200")
baudRate=QSerialPort::Baud1200;
else if(ui->baundrate_Cb->currentText()=="2400")
baudRate=QSerialPort::Baud2400;
else if(ui->baundrate_Cb->currentText()=="4800")
baudRate=QSerialPort::Baud4800;
else if(ui->baundrate_Cb->currentText()=="9600")
baudRate=QSerialPort::Baud9600;
else if(ui->baundrate_Cb->currentText()=="19200")
baudRate=QSerialPort::Baud19200;
else if(ui->baundrate_Cb->currentText()=="38400")
baudRate=QSerialPort::Baud38400;
else if(ui->baundrate_Cb->currentText()=="57600")
baudRate=QSerialPort::Baud57600;
else if(ui->baundrate_Cb->currentText()=="115200")
baudRate=QSerialPort::Baud115200;
// 获取串口数据位
if(ui->databit_Cb->currentText()=="5")
dataBits=QSerialPort::Data5;
else if(ui->databit_Cb->currentText()=="6")
dataBits=QSerialPort::Data6;
else if(ui->databit_Cb->currentText()=="7")
dataBits=QSerialPort::Data7;
else if(ui->databit_Cb->currentText()=="8")
dataBits=QSerialPort::Data8;
// 获取串口停止位
if(ui->stopbit_Cb->currentText()=="1")
stopBits=QSerialPort::OneStop;
else if(ui->stopbit_Cb->currentText()=="1.5")
stopBits=QSerialPort::OneAndHalfStop;
else if(ui->stopbit_Cb->currentText()=="2")
stopBits=QSerialPort::TwoStop;
// 获取串口奇偶校验位
if(ui->checkbit_Cb->currentText() == "none"){
checkBits = QSerialPort::NoParity;
}else if(ui->checkbit_Cb->currentText() == "奇校验"){
checkBits = QSerialPort::OddParity;
}else if(ui->checkbit_Cb->currentText() == "偶校验"){
checkBits = QSerialPort::EvenParity;
}
// 初始化串口属性,设置 端口号、波特率、数据位、停止位、奇偶校验位数
serialPort->setPortName(ui->serial_Cb->currentText());
serialPort->setBaudRate(baudRate);
serialPort->setDataBits(dataBits);
serialPort->setStopBits(stopBits);
serialPort->setParity(checkBits);
// 根据初始化好的串口属性,打开串口
// 如果打开成功,反转打开按钮显示和功能。打开失败,无变化,并且弹出错误对话框。
if(ui->open_serial_Bt->text() == "打开串口"){
if(serialPort->open(QIODevice::ReadWrite) == true){
//QMessageBox::
ui->open_serial_Bt->setText("关闭串口");
// 让端口号下拉框不可选,避免误操作(选择功能不可用,控件背景为灰色)
ui->serial_Cb->setEnabled(false);
}else{
QMessageBox::critical(this, "错误提示", "串口打开失败!!!\r\n该串口可能被占用\r\n请选择正确的串口");
}
//statusBar 状态栏显示端口状态
QString sm = "%1 OPENED, %2, 8, NONE, 1";
QString status = sm.arg(serialPort->portName()).arg(serialPort->baudRate());
lblPortState->setText(status);
lblPortState->setStyleSheet("color:green");
}else{
serialPort->close();
ui->open_serial_Bt->setText("打开串口");
// 端口号下拉框恢复可选,避免误操作
ui->serial_Cb->setEnabled(true);
//statusBar 状态栏显示端口状态
QString sm = "%1 CLOSED";
QString status = sm.arg(serialPort->portName());
lblPortState->setText(status);
lblPortState->setStyleSheet("color:red");
}
}
void MainWindow::on_send_Bt_clicked()
{
QByteArray array;
//Hex复选框
if(ui->send_hex_Chb->checkState() == Qt::Checked){
//array = QString2Hex(data); //HEX 16进制
array = QByteArray::fromHex(ui->textEdit_send->toPlainText().toUtf8()).data();
}else{
//array = data.toLatin1(); //ASCII
array = ui->textEdit_send->toPlainText().toLocal8Bit().data();
}
if(ui->send_line_Chb->checkState() == Qt::Checked){
array.append("\r\n");
}
// 如发送成功,会返回发送的字节长度。失败,返回-1。
int a = serialPort->write(array);
// 发送字节计数并显示
if(a > 0)
{
// 发送字节计数
sendNum += a;
// 状态栏显示计数值
setNumOnLabel(lblSendNum, "S: ", sendNum);
}
}
void MainWindow::on_clear_recv_Bt_clicked()
{
ui->textEdit_recv->clear();
// 清除接收字节计数
sendNum = 0;
// 状态栏显示计数值
setNumOnLabel(lblSendNum, "S: ", sendNum);
}
void MainWindow::on_clear_send_Bt_clicked()
{
ui->textEdit_send->clear();
// 清除发送字节计数
sendNum = 0;
// 状态栏显示计数值
setNumOnLabel(lblSendNum, "S: ", sendNum);
}
// 定时发送开关 选择复选框
void MainWindow::on_chkTimSend_stateChanged(int arg1)
{
// 获取复选框状态,未选为0,选中为2
if(arg1 == 0){
timSend->stop();
// 时间输入框恢复可选
ui->txtSendMs->setEnabled(true);
}else{
// 对输入的值做限幅,小于10ms会弹出对话框提示
if(ui->txtSendMs->text().toInt() >= 10){
timSend->start(ui->txtSendMs->text().toInt());// 设置定时时长,重新计数
// 让时间输入框不可选,避免误操作(输入功能不可用,控件背景为灰色)
ui->txtSendMs->setEnabled(false);
}else{
ui->autosend_Chb->setCheckState(Qt::Unchecked);
QMessageBox::critical(this, "错误提示", "定时发送的最小间隔为 10ms\r\n请确保输入的值 >=10");
}
}
}
/*手动实现接收数据函数*/
void MainWindow::manual_serialPortReadyRead()
{
QByteArray recBuf = serialPort->readAll();
QString str_rev;
// 接收字节计数
recvNum += recBuf.size();
// 状态栏显示计数值
setNumOnLabel(lblRecvNum, "R: ", recvNum);
if(ui->recv_hex_Chb->checkState() == false){
if(ui->recv_time_Chb->checkState() == Qt::Checked){
QDateTime nowtime = QDateTime::currentDateTime();
str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
str_rev += QString(recBuf).append("\r\n");
}
else{
// 在当前位置插入文本,不会发生换行。如果没有移动光标到文件结尾,会导致文件超出当前界面显示范围,界面也不会向下滚动。
//ui->recvEdit->appendPlainText(buf);
if(ui->recv_autoline_Chb->checkState() == Qt::Checked){
str_rev = QString(recBuf).append("\r\n");
}
else
{
str_rev = QString(recBuf);
}
}
}else{
// 16进制显示,并转换为大写
QString str1 = recBuf.toHex().toUpper();//.data();
// 添加空格
QString str2;
for(int i = 0; i<str1.length (); i+=2)
{
str2 += str1.mid (i,2);
str2 += " ";
}
if(ui->recv_time_Chb->checkState() == Qt::Checked)
{
QDateTime nowtime = QDateTime::currentDateTime();
str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
str_rev += str2.append("\r\n");
}
else
{
if(ui->recv_autoline_Chb->checkState() == Qt::Checked)
str_rev += str2.append("\r\n");
else
str_rev = str2;
}
}
ui->textEdit_recv->insertPlainText(str_rev);
ui->textEdit_recv->moveCursor(QTextCursor::End);
}
// 状态栏标签显示计数值
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)
{
// 标签显示
QString strN;
strN.sprintf("%ld", num);
QString str = strS + strN;
lbl->setText(str);
}
3.3 mainwindow.ui源文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>581</width>
<height>541</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>191</width>
<height>311</height>
</rect>
</property>
<property name="title">
<string>串口配置</string>
</property>
<widget class="QWidget" name="gridLayoutWidget_2">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>169</width>
<height>281</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="Serial_check_Bt">
<property name="minimumSize">
<size>
<width>93</width>
<height>28</height>
</size>
</property>
<property name="text">
<string>检测串口</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="open_serial_Bt">
<property name="minimumSize">
<size>
<width>93</width>
<height>28</height>
</size>
</property>
<property name="text">
<string>打开串口</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0" columnstretch="0,0">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="3" column="0">
<widget class="QLabel" name="label_databit">
<property name="minimumSize">
<size>
<width>72</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>数据位:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_parity">
<property name="minimumSize">
<size>
<width>72</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>校验位:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="serial_Cb">
<property name="minimumSize">
<size>
<width>87</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>15</height>
</size>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_stopbit">
<property name="minimumSize">
<size>
<width>72</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>停止位:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="stopbit_Cb">
<property name="minimumSize">
<size>
<width>87</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>15</height>
</size>
</property>
<item>
<property name="text">
<string>none</string>
</property>
</item>
<item>
<property name="text">
<string>奇校验</string>
</property>
</item>
<item>
<property name="text">
<string>偶校验</string>
</property>
</item>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="checkbit_Cb">
<property name="minimumSize">
<size>
<width>87</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>15</height>
</size>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>1.5</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="baundrate_Cb">
<property name="minimumSize">
<size>
<width>87</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>15</height>
</size>
</property>
<property name="currentText">
<string>9600</string>
</property>
<property name="currentIndex">
<number>3</number>
</property>
<item>
<property name="text">
<string>1200</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
<item>
<property name="text">
<string>57600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_serialport">
<property name="minimumSize">
<size>
<width>72</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>端口号:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_baudrate">
<property name="minimumSize">
<size>
<width>72</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>波特率:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="databit_Cb">
<property name="minimumSize">
<size>
<width>87</width>
<height>22</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>76</width>
<height>15</height>
</size>
</property>
<property name="currentText">
<string>5</string>
</property>
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>30</x>
<y>350</y>
<width>191</width>
<height>81</height>
</rect>
</property>
<property name="title">
<string>接收设置</string>
</property>
<widget class="QWidget" name="formLayoutWidget_2">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>189</width>
<height>56</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="clear_recv_Bt">
<property name="text">
<string>清空接收</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="recv_hex_Chb">
<property name="text">
<string>Hex接收</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="recv_time_Chb">
<property name="text">
<string>时间戳</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="recv_autoline_Chb">
<property name="text">
<string>自动换行</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>30</x>
<y>440</y>
<width>191</width>
<height>71</height>
</rect>
</property>
<property name="title">
<string>发送设置</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>183</width>
<height>49</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QCheckBox" name="send_hex_Chb">
<property name="text">
<string>Hex发送</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QCheckBox" name="send_line_Chb">
<property name="text">
<string>发送新行</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="autosend_Chb">
<property name="text">
<string>自动发送</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="txtSendMs">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>ms</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_4">
<property name="geometry">
<rect>
<x>220</x>
<y>30</y>
<width>351</width>
<height>481</height>
</rect>
</property>
<property name="title">
<string>数据交互</string>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>341</width>
<height>451</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>发送数据</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTextEdit" name="textEdit_send"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>接收数据</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QTextEdit" name="textEdit_recv">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="send_Bt">
<property name="text">
<string>发送数据</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="clear_send_Bt">
<property name="text">
<string>清空发送区</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
如果一切顺利的话,点击左下角的三角符号进行编译运行就可以测试效果了。
4. 打包可执行文件
当经过上面的步骤,编译后能成功运行。这时如果希望像我们平时用到的各种免安装的exe工具一样可以分享给其他小伙伴使用,就需要再打包一下才行。
传送门:【Qt安装与简易串口控制Arduino开发板小灯教程】
windeployqt Serial.exe
测试软件,点击运行启动app,电脑连接一个USB转TTL模块,TX接RX,勾选时间戳。然后点击检测串口,选择对应端口号打开串口,在输入文本框中输入12abc
,点击发送,然后就可以收到数据啦😍😍😍👍
5. 总结
🥳🥳🥳现在,我们在本教程中,您学习了【QT串口助手】。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣
如果你有任何问题,可以通过下面的二维码加入鹏鹏小分队,期待与你思维的碰撞😘😘😘
参考文献:
相关好文推荐:
- QT初体验:手把手带你写一个自己的串口助手
- 【Qt安装与简易串口控制Arduino开发板小灯教程】