window端QT开发之串口数据接收处理

本文介绍了在Windows环境下使用QT进行串口通信,特别是数据接收的处理方式。通过QSerialPort实现串口数据的接收,并利用定时器进行超时检测,确保数据完整后再进行处理。

写在前面

串口QSerialPort,本篇先讲讲串口的数据接收
.pro中添加QT += serialport

头文件

#include <QSerialPort>
#include <QSerialPortInfo>
#include <QIODevice>

定义全局变量

static QSerialPort * m_serialport=new QSerialPort();
static QByteArray     uartRecvBuffer;

接收回调

绑定信号槽,收到数据后

在使用 Qt 开发串口通信程序时,可以利用 `QSerialPort` 和 `QSerialPortInfo` 类来实现串口的配置、数据接收与发送。下面是一个整的示例,展示如何使用 Qt 接收串口数据并在 `QTextEdit` 或 `QPlainTextEdit` 中实时显示。 --- ### ✅ 功能说明: - 扫描可用串口并填充到下拉框(`QComboBox`) - 打开/关闭串口 - 实时接收串口数据并显示在文本框中 - 支持 UTF-8 编码显示(也可改为 HEX 显示) --- ### 🛠 使用前准备 确保在 `.pro` 文件中添加: ```qmake QT += serialport widgets ``` --- ### 📦 整代码示例(基于 QWidget) #### 1. `mainwindow.h` ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> #include <QTextEdit> #include <QComboBox> #include <QPushButton> #include <QLabel> #include <QVBoxLayout> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void onOpenCloseClicked(); void onReadyRead(); // 接收数据槽函数 void updateSerialPorts(); // 更新串口列表 private: QSerialPort *serial; QTextEdit *textDisplay; QComboBox *portBox; QComboBox *baudBox; QPushButton *openButton; QLabel *statusLabel; void setupUI(); }; #endif // MAINWINDOW_H ``` --- #### 2. `mainwindow.cpp` ```cpp #include "mainwindow.h" #include <QVBoxLayout> #include <QHBoxLayout> #include <QTimer> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), serial(new QSerialPort(this)) { setupUI(); // 初始化波特率选择 baudBox->addItems({"9600", "19200", "38400", "57600", "115200"}); baudBox->setCurrentText("115200"); // 更新串口列表 updateSerialPorts(); // 设置定时器定期刷新串口列表(可选) QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &MainWindow::updateSerialPorts); timer->start(2000); // 每2秒刷新一次设备列表 // 连接信号槽 connect(openButton, &QPushButton::clicked, this, &MainWindow::onOpenCloseClicked); connect(serial, &QSerialPort::readyRead, this, &MainWindow::onReadyRead); } MainWindow::~MainWindow() { if (serial->isOpen()) serial->close(); } void MainWindow::setupUI() { QWidget *centralWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout; // 控件 portBox = new QComboBox; baudBox = new QComboBox; openButton = new QPushButton("打开串口"); textDisplay = new QTextEdit; textDisplay->setReadOnly(true); statusLabel = new QLabel("串口状态: 已关闭"); // 布局 QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(new QLabel("串口号:")); topLayout->addWidget(portBox); topLayout->addWidget(new QLabel("波特率:")); topLayout->addWidget(baudBox); topLayout->addWidget(openButton); mainLayout->addLayout(topLayout); mainLayout->addWidget(textDisplay); mainLayout->addWidget(statusLabel); centralWidget->setLayout(mainLayout); setCentralWidget(centralWidget); setWindowTitle("Qt 串口接收显示"); resize(600, 400); } void MainWindow::updateSerialPorts() { QString current = portBox->currentText(); portBox->clear(); for (const QSerialPortInfo &info : QSerialPortInfo::availablePorts()) { portBox->addItem(info.portName() + " - " + info.description(), info.portName()); } // 尝试恢复之前的选中项 int index = portBox->findData(current); if (index != -1) { portBox->setCurrentIndex(index); } } void MainWindow::onOpenCloseClicked() { if (serial->isOpen()) { serial->close(); openButton->setText("打开串口"); statusLabel->setText("串口状态: 已关闭"); } else { QString portName = portBox->currentData().toString(); if (portName.isEmpty()) { textDisplay->append("错误:未选择有效串口!"); return; } serial->setPortName(portName); serial->setBaudRate(baudBox->currentText().toInt()); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); if (serial->open(QIODevice::ReadOnly)) { // 只读接收模式 openButton->setText("关闭串口"); statusLabel->setText(QString("串口状态: 已打开 (%1)").arg(portName)); textDisplay->append(">> 串口已打开,开始监听..."); } else { textDisplay->append("错误:无法打开串口:" + serial->errorString()); } } } void MainWindow::onReadyRead() { QByteArray data = serial->readAll(); QString str; // 方式一:作为文本显示(UTF-8) str = QString::fromUtf8(data); // (可选)方式二:以十六进制显示 // str = data.toHex(' ').toUpper(); textDisplay->moveCursor(QTextCursor::End); textDisplay->insertPlainText(str); textDisplay->ensureCursorVisible(); // 自动滚动到底部 } ``` --- #### 3. `main.cpp` ```cpp #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow w; w.show(); return app.exec(); } ``` --- ### 🔍 解释说明: - **`QSerialPort`**:用于管理串口连接,支持异步读写。 - **`readyRead()` 信号**:当有新数据到达时触发,我们在 `onReadyRead()` 中读取所有可用数据。 - **`readAll()`**:一次性读取缓冲区中的全部数据,避免遗漏。 - **文本编码处理**:默认按 UTF-8 解码,适用于打印字符串;若需解析单字节协议或调试二进制数据,建议切换为 HEX 显示。 - **自动刷新串口列表**:通过 `QTimer` 定期调用 `updateSerialPorts()`,方便热插拔识别。 --- ### 💡 建议增强功能(进阶方向): - 添加“清空显示”按钮 - 添加 HEX / 文本 显示切换选项 - 添加串口发送区域 - 数据保存到文件 - 使用线程防止界面卡顿(对于高速数据流) --- ### ✅ 效果预览(运行后): - 界面顶部显示串口和波特率选择 + “打开串口”按钮 - 中间大文本框实时显示接收到的内容 - 底部状态栏提示当前串口状态 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值