2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > (Qt)windows下串口检测-热插拔监测 获取可用串口

(Qt)windows下串口检测-热插拔监测 获取可用串口

时间:2018-08-22 03:11:12

相关推荐

(Qt)windows下串口检测-热插拔监测 获取可用串口

文章目录

1、主要功能2、适用系统3、源码地址4、实现效果5、实现代码

1、主要功能

通过继承QAbstractNativeEventFilter接口实现串口热插拔监测功能;通过在QWidget中重写nativeEvent实现串口热插拔监测功能;通过一个函数获取系统中所有可用串口名;自动添加、移除可用串口。

2、适用系统

Windows Win32 API 的编程参考Windows 驱动程序文档

3、源码地址

/mahuifa/DeviceManagement.git/mahuifa/DeviceManagement.git

4、实现效果

5、实现代码

comchange.h

/******************************************************************************* @文件名 comchange.h* @功能通过继承于QAbstractNativeEventFilter来监测串口热插拔由于windows消息会发给每一个窗口,* 所以如果打开多个窗或者使用到如QComboBox之类的控件,当串口插入或者拔出时会触发多次事件,* 在这里我使用的解决方法时传入一个窗口句柄,通过窗口句柄过滤事件,但不知道有没有其它更好的办法。** @开发者(作者)* @时间 /11/15* @备注*****************************************************************************/#ifndef COMCHANGE_H#define COMCHANGE_H#include <QObject>#include <qabstractnativeeventfilter.h>#include <windows.h>#include "dbt.h"class ComChange : public QObject, public QAbstractNativeEventFilter{Q_OBJECTpublic:static ComChange* getInstance();static QStringList getAvailablePort();void setHWND(HWND hwnd);private:explicit ComChange(QObject *parent = nullptr);protected:bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);signals:/*** @brief 传出串口热插拔状态* @param name 串口名* @param flag true:插入 false:拔出*/void comStatus(QString name, bool flag);private:static ComChange* m_comChange;HWND m_hwnd;};#endif // COMCHANGE_H

comchange.cpp

#include "comchange.h"#include <QApplication>#include <QMutex>#include <QSerialPort>#include <QSerialPortInfo>#include <qdebug.h>ComChange* ComChange::m_comChange = nullptr;ComChange *ComChange::getInstance(){if(m_comChange == nullptr){static QMutex mutex; //实例互斥锁。QMutexLocker locker(&mutex); //加互斥锁。if(m_comChange == nullptr){m_comChange = new ComChange();}}return m_comChange;}/*** @brief 获取系统中所有可用的串口名* @return*/QStringList ComChange::getAvailablePort(){QStringList strName;foreach(const QSerialPortInfo& info, QSerialPortInfo::availablePorts()){QSerialPort port(info);if(port.open(QIODevice::ReadWrite)){strName << info.portName();port.close();}}return strName;}/*** @brief 设置窗口句柄用于过滤事件* @param hwnd*/void ComChange::setHWND(HWND hwnd){this->m_hwnd = hwnd;}ComChange::ComChange(QObject *parent) : QObject(parent){qApp->installNativeEventFilter(this); // 安装事件过滤器}bool ComChange::nativeEventFilter(const QByteArray &eventType, void *message, long *result){MSG* msg = reinterpret_cast<MSG*>(message);if(msg->message == WM_DEVICECHANGE// 通知应用程序设备或计算机的硬件配置发生更改。&& msg->hwnd == this->m_hwnd) // 过滤事件{PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;switch (msg->wParam){case DBT_DEVICEARRIVAL: // 插入{if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) // 设备类型为串口{PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;QString strName = QString::fromWCharArray(lpdbv->dbcp_name); //插入的串口名emit comStatus(strName, true);}break;}case DBT_DEVICEREMOVECOMPLETE:// 拔出{if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) // 设备类型为串口{PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;QString strName = QString::fromWCharArray(lpdbv->dbcp_name); //拔出的串口名emit comStatus(strName, false);}break;}default:break;}}return false;}

widget.h

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACEnamespace Ui {class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected:bool nativeEvent(const QByteArray &eventType, void *message, long *result);void on_comStatus(QString name, bool flag);private:Ui::Widget *ui;};#endif // WIDGET_H

widget.cpp

#include "widget.h"#include "ui_widget.h"#include <QDebug>#include <windows.h>#include "dbt.h"#include "comchange.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);// 第二种方法ComChange::getInstance()->setHWND((HWND)this->winId());connect(ComChange::getInstance(), &ComChange::comStatus, this, &Widget::on_comStatus);ui->comboBox->addItems(ComChange::getAvailablePort());}Widget::~Widget(){delete ui;}/*** @brief第一种方法* @param eventType* @param message* @param result* @return*/bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result){MSG* msg = reinterpret_cast<MSG*>(message);if(msg->message == WM_DEVICECHANGE)// 通知应用程序设备或计算机的硬件配置发生更改。{PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;switch (msg->wParam){case DBT_DEVICEARRIVAL: // 插入{if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) // 设备类型为串口{PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;QString strName = QString::fromWCharArray(lpdbv->dbcp_name); //插入的串口名qDebug() << strName;}break;}case DBT_DEVICEREMOVECOMPLETE:// 拔出{if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) // 设备类型为串口{PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;QString strName = QString::fromWCharArray(lpdbv->dbcp_name); //拔出的串口名qDebug() << strName;}break;}default:break;}}return false;}void Widget::on_comStatus(QString name, bool flag){if(flag){ui->comboBox->addItem(name);}else{ui->comboBox->removeItem(ui->comboBox->findText(name));}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。