创建工程
布局UI界面
设置名称
设置数据
设置波特率
波特率默认9600
设置数据位
数据位默认8
设置停止位
设置校验位
调整串口设置、接收设置、发送设置为Group Box
修改配置
QT += core gui serialport
代码详解
mianwindow.h
首先在mianwindow.h当中定义一个串口指针
public:
QSerialPort *serialPort;//定义串口指针
并且添加头文件
#include <QMainWindow>
#include <QSerialPort>
#include <QString>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QTimer>
#include <QPainter>
QMainWindow:是 Qt 中主窗口的基类,提供了主窗口的基本功能,如菜单栏、工具栏等。
QSerialPort:用于串口通信的类,可实现与串口设备的数据交互。
QString:Qt 中用于处理字符串的类,提供了丰富的字符串操作方法。
QSerialPortInfo:用于获取系统中可用串口的信息,如串口名称、描述等。
QMessageBox:用于显示消息框,可用于提示用户信息、警告或错误。
QTimer:用于实现定时器功能,可在指定时间间隔后触发特定操作。
QPainter:用于在窗口或其他绘图设备上进行绘图操作。
private:
// 发送、接收字节计数
long sendNum, recvNum;
QLabel *lblSendNum;
QLabel *lblRecvNum;
QLabel *lblPortState;
void setNumOnLabel(QLabel *lbl, QString strS, long num);
// 定时发送-定时器
QTimer *timSend;
Ui::MainWindow *ui;:指向由 Qt Designer 生成的用户界面类的指针,用于访问和操作界面元素。
long sendNum, recvNum;:用于记录发送和接收的字节数。
QLabel *lblSendNum;、QLabel *lblRecvNum;、QLabel *lblPortState;:分别指向用于显示发送字节数、接收字节数和串口状态的 QLabel 控件。
void setNumOnLabel(QLabel *lbl, QString strS, long num);:私有成员函数,用于将指定的数字显示在 QLabel 控件上。
QTimer *timSend;:指向 QTimer 对象的指针,用于实现定时发送功能。
private slots:
/*手动连接槽函数*/
void manual_serialPortReadyRead();
/*以下为mainwindow.ui文件中点击“转到槽”自动生成的函数*/
void on_openBt_clicked();
void on_sendBt_clicked();
void on_clearBt_clicked();
void on_btnClearSend_clicked();
void on_chkTimSend_stateChanged(int arg1);
void on_btnSerialCheck_clicked();
void manual_serialPortReadyRead();:手动连接的槽函数,当串口有数据可读时触发。
void on_openBt_clicked();:当 openBt 按钮被点击时触发的槽函数,通常用于打开串口。
void on_sendBt_clicked();:当 sendBt 按钮被点击时触发的槽函数,通常用于发送数据。
void on_clearBt_clicked();:当 clearBt 按钮被点击时触发的槽函数,通常用于清除接收区的数据。
void on_btnClearSend_clicked();:当 btnClearSend 按钮被点击时触发的槽函数,通常用于清除发送区的数据。
void on_chkTimSend_stateChanged(int arg1);:当 chkTimSend 复选框的状态改变时触发的槽函数,用于处理定时发送的开启和关闭。
void on_btnSerialCheck_clicked();:当 btnSerialCheck 按钮被点击时触发的槽函数,通常用于检查系统中可用的串口。
mianwindow.cpp
MainWindow::MainWindow(QWidget *parent)
serialPort = new QSerialPort(this);
connect(serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));
将串口的 readyRead() 信号与自定义的槽函数 manual_serialPortReadyRead() 进行连接。
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);
sender:发送信号的对象,这里是 serialPort,即 QSerialPort 对象。
signal:发送的信号,使用 SIGNAL 宏将信号名称转换为字符串。readyRead() 是 QSerialPort 类的一个信号,当串口接收到新的数据时会自动发出该信号。
receiver:接收信号的对象,这里是 this,即 MainWindow 对象本身。
method:接收信号后要执行的槽函数,使用 SLOT 宏将槽函数名称转换为字符串。manual_serialPortReadyRead() 是在 MainWindow 类中定义的一个私有槽函数,用于处理串口接收到的数据。
type:连接类型,默认为 Qt::AutoConnection,表示根据发送者和接收者所在的线程自动选择合适的连接方式。
ui->serailCb->clear();
//通过QSerialPortInfo查找可用串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
ui->serailCb->addItem(info.portName());
}
ui->serailCb->clear();:
ui 是一个指向 Ui::MainWindow 类对象的指针,Ui::MainWindow 类通常是由 Qt Designer 生成的,用于管理主窗口的用户界面元素。
serailCb 是用户界面中的一个下拉列表控件(可能是 QComboBox 类型)。
clear() 是 QComboBox 类的一个成员函数,用于清除下拉列表中的所有现有选项。这一步是为了确保在添加新的串口选项之前,下拉列表中没有其他无关的选项。
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()):
foreach 是 Qt 提供的一个用于遍历容器的宏。在这里,它用于遍历 QSerialPortInfo::availablePorts() 返回的可用串口信息列表。
QSerialPortInfo 是 Qt 中用于获取串口设备信息的类,例如串口名称、描述、制造商等。
availablePorts() 是 QSerialPortInfo 类的一个静态成员函数,它返回一个包含系统中所有可用串口信息的 QList 列表。
const QSerialPortInfo &info 声明了一个常量引用 info,用于在每次迭代中存储当前遍历到的串口信息对象。通过引用的方式,可以避免不必要的对象拷贝,提高效率。
ui->serailCb->addItem(info.portName());:
对于 foreach 循环中的每一个串口信息对象 info,调用 portName() 成员函数获取该串口的名称。
然后使用 ui->serailCb->addItem() 将获取到的串口名称作为一个新的选项添加到下拉列表 serailCb 中。这样,用户就可以在下拉列表中选择系统中可用的串口设备了。
// 发送、接收计数清零
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");
sendNum 和 recvNum 是在 MainWindow 类中定义的用于记录发送和接收字节数的变量。
statusBar() 是 QMainWindow 类的一个成员函数,用于获取主窗口的状态栏对象。sBar 是一个指向 QStatusBar 对象的指针,通过这个指针可以对状态栏进行操作,比如添加控件、设置文本等。
lblSendNum、lblRecvNum 和 lblPortState 是在 MainWindow 类中定义的指向 QLabel 对象的指针。
new QLabel(this) 动态创建了三个 QLabel 控件,分别用于显示发送字节数、接收字节数和串口连接状态。this 作为参数传递给 QLabel 的构造函数,表示将当前 MainWindow 对象作为这些 QLabel 控件的父对象,这样当 MainWindow 对象被销毁时,这些 QLabel 控件也会被自动销毁,避免内存泄漏。
setText() 是 QLabel 类的一个成员函数,用于设置标签上显示的文本内容。将 lblPortState 标签的文本设置为 “Connected”,表示串口已经成功连接。
// 设置标签最小大小
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);
lblSendNum、lblRecvNum 和 lblPortState 是之前创建的 QLabel 控件指针,分别用于显示发送字节数、接收字节数和串口连接状态。
setMinimumSize(int width, int height) 是 QLabel 类从 QWidget 继承而来的一个成员函数,用于设置控件的最小宽度和高度。这里将 lblSendNum 和 lblRecvNum 的最小大小设置为宽 100 像素、高 20 像素,将 lblPortState 的最小大小设置为宽 550 像素、高 20 像素。这样做可以确保在界面布局变化时,这些标签不会被压缩到小于指定的大小,保证显示内容的完整性。
setNumOnLabel 是 MainWindow 类中定义的一个私有成员函数,用于将指定的字符串和数字组合后显示在 QLabel 控件上。
对于 lblSendNum,传递的参数 "S: " 作为前缀,sendNum 是之前清零后的发送字节数计数,函数会将它们组合成一个字符串并显示在 lblSendNum 标签上,用于提示用户发送数据的字节数。
同理,对于 lblRecvNum,传递的参数 "R: " 作为前缀,recvNum 是接收字节数计数,函数会将组合后的字符串显示在 lblRecvNum 标签上,用于提示用户接收数据的字节数。
sBar 是之前通过 statusBar() 函数获取的主窗口状态栏指针。
addPermanentWidget(QWidget * widget) 是 QStatusBar 类的一个成员函数,用于将一个 QWidget 类型的控件(这里是 QLabel 控件)永久添加到状态栏中。状态栏中的控件通常按照添加的顺序从左到右排列,但由于这里注释提到 “从右往左依次添加”,实际效果是 lblPortState 在最右边,然后是 lblSendNum,最后是 lblRecvNum 在最左边。这样在状态栏中就可以依次显示串口连接状态、发送字节数和接收字节数,方便用户查看相关信息。
// 定时发送-定时器
timSend = new QTimer;
timSend->setInterval(1000);// 设置默认定时时长1000ms
connect(timSend, &QTimer::timeout, this, [=](){
on_sendBt_clicked();
});
timSend 是 MainWindow 类中定义的一个指向 QTimer 对象的指针。
new QTimer 使用 new 运算符在堆上动态创建一个 QTimer 对象,该对象用于实现定时功能。创建后,timSend 指针指向这个新创建的 QTimer 对象。
setInterval(int msec) 是 QTimer 类的一个成员函数,用于设置定时器的时间间隔,单位是毫秒(ms)。
这里将定时器的时间间隔设置为 1000 毫秒,也就是 1 秒。意味着定时器每隔 1 秒就会触发一次超时信号 timeout()。
connect 是 Qt 中用于连接信号和槽的函数,它建立了信号发送者、信号、信号接收者和槽函数之间的关联。
timSend:信号的发送者,即刚刚创建的 QTimer 对象。
&QTimer::timeout:发送的信号,timeout() 是 QTimer 类的一个信号,当定时器超时时会自动发出该信号。
this:信号的接收者,这里是 MainWindow 对象本身。
={ on_sendBt_clicked(); }:一个 Lambda 表达式,作为槽函数。[=] 表示以值捕获的方式捕获 Lambda 表达式所在作用域中的所有变量,这样 Lambda 表达式内部就可以访问这些变量。on_sendBt_clicked() 是 MainWindow 类中定义的一个槽函数,通常用于处理发送按钮被点击时的操作,比如发送数据。当定时器超时发出 timeout() 信号时,这个 Lambda 表达式会被执行,进而调用 on_sendBt_clicked() 函数,实现定时发送数据的功能。
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)
{
// 标签显示
// QString strN;
// strN.sprintf("%ld", num);
// QString strN = strFormat.arg(num);
QString strN = QString::number(num);
QString str = strS + strN;
lbl->setText(str);
}
函数名称:setNumOnLabel,这是 MainWindow 类的一个成员函数,用于将一个字符串前缀和一个长整型数字组合成一个新的字符串,并将其显示在指定的 QLabel 控件上。
参数:
QLabel *lbl:一个指向 QLabel 控件的指针,该函数会将组合后的字符串显示在这个 QLabel 控件上。
QString strS:一个 QString 类型的字符串,作为组合字符串的前缀。
long num:一个长整型数字,将被转换为字符串并与前缀组合。
返回值:void,表示该函数不返回任何值。
QString::number() 是 QString 类的一个静态成员函数,用于将各种数值类型(如 int、long、double 等)转换为 QString 类型的字符串。这里将传入的长整型数字 num 转换为对应的字符串,并存储在 strN 变量中。
void MainWindow::on_sendBt_clicked()
/*发送数据*/
void MainWindow::on_sendBt_clicked()
{
QByteArray array;
//Hex复选框
if(ui->chk_send_hex->checkState() == Qt::Checked){
//array = QString2Hex(data); //HEX 16进制
array = QByteArray