Qt 监控串口设备热插拔的方法
一、监控串口设备热插拔的方法
Qt 提供了多种方法来监控串口设备的热插拔事件,可以通过以下方法实现:
1、使用 QSerialPortInfo 轮询检测
定期调用 QSerialPortInfo::availablePorts()
检查可用串口列表的变化。通过比较前后两次的列表差异,可以判断设备是否被插入或拔出。
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [=]() {static QList<QSerialPortInfo> previousPorts = QSerialPortInfo::availablePorts();QList<QSerialPortInfo> currentPorts = QSerialPortInfo::availablePorts();if (currentPorts.size() > previousPorts.size()) {// 新设备插入} else if (currentPorts.size() < previousPorts.size()) {// 设备拔出}previousPorts = currentPorts;
});
timer->start(1000); // 每秒检查一次
2、使用平台特定事件监听(Linux)
在 Linux 系统下,可以通过监听 udev 事件来检测串口设备的热插拔。使用 QUdev
或直接通过文件系统监控 /dev
目录变化。
QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
watcher->addPath("/dev");
connect(watcher, &QFileSystemWatcher::directoryChanged, [=](const QString &path) {// 检查 /dev 目录变化
});
3、重写nativeEvent函数
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
{MSG* msg = reinterpret_cast<MSG*>(message);if(msg->message == WM_DEVICECHANGE){qDebug()<<QSerialPortInfo::availablePorts().size();foreach (auto info, QSerialPortInfo::availablePorts()){qDebug()<<info.portName();}}return QMainWindow::nativeEvent(eventType, message, result);
}
二、实例展示
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSerialPortInfo>QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();protected:bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <windows.h>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
{MSG* msg = reinterpret_cast<MSG*>(message);if(msg->message == WM_DEVICECHANGE){qDebug()<<QSerialPortInfo::availablePorts().size();foreach (auto info, QSerialPortInfo::availablePorts()){qDebug()<<info.portName();}}return QMainWindow::nativeEvent(eventType, message, result);
}