Qt 串口拔出提示
解决问题:我本人在做项目的时候,在编写一个桌面工具软件时,我想着增加一个串口插拔提示的框,方便使用者判断串口插拔的情况,避免有些情况下串口接触不良导致数据收发收到影响,从而影响团队中的项目进度。今天我们就此解决这个问题。
目录
一、说明
在日常的工作中,项目中,我们经常遇到使用串口的通讯的场景,这时候我们可能会对串口的插拔进行提示。
Qt的主要实现就是继承自QAbstractNativeEventFilter类,对此类中的nativeEventFilter函数进行重写,完成的。
QAbstractNativeEventFilter类主要就是提供捕获本机操作系统级消息,比如MSG或XCB事件。
二、事件过滤
QAbstractNativeEventFilter类提供了3个函数:
其中包含纯虚函数nativeEventFilte,所以我们在相关的子类中,需要重写这个函数,来实现我们过滤相关事件的目的。
virtual bool
nativeEventFilter(const QByteArray &eventType, void *message, long *result) = 0
nativeEventFilter函数的Qt解释如下:它会接收到本地事件,我们只需要在这个函数里实现我们对应的事件处理操作就行了。
在Qt的文档介绍里还给了示例(Linux):
Linux example
class MyXcbEventFilter : public QAbstractNativeEventFilter
{
public:
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
{
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
// ...
}
return false;
}
};
windows下的实现,见下面的 三、实现 章节。
比如说:我们实现的是串口的事件,我们需要过滤对应的DBT_DEVTYP_PORT就行了。
三、实现
#include <Windows.h>
#include <dbt.h>
bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
int msgType = msg->message;
if (msgType == WM_DEVICECHANGE) {
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
switch (msg->wParam)
{
case DBT_DEVICEREMOVECOMPLETE:
if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT)
{
PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
QString port = QString::fromWCharArray(lpdbv->dbcp_name);//拔出的串口名
if( port == ui->com_num_comboBox->currentText() )
{
QMessageBox::information(this, QStringLiteral("警告"),\
QStringLiteral("串口")+port+QStringLiteral("已移除!"), QMessageBox::Cancel);
ui->com_open_Btn->setText(QStringLiteral("打开"));
m_bSerialOpenFlag = false;
QStringList vctPortName;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
vctPortName << info.portName();
}
ui->com_num_comboBox->clear();
ui->com_num_comboBox->addItems(vctPortName);
}
}
break;
case DBT_DEVICEARRIVAL:
if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) {
PDEV_BROADCAST_PORT lpdbv = (PDEV_BROADCAST_PORT)lpdb;
QString port = QString::fromWCharArray(lpdbv->dbcp_name);//插入的串口名
QMessageBox::information(this, QStringLiteral("提示"),\
QStringLiteral("串口")+port+QStringLiteral("已连
接 !"), QMessageBox::Cancel);
}
break;
case DBT_DEVNODES_CHANGED:
break;
default:
break;
}
}
return QWidget::nativeEvent(eventType, message, result);
}
同时,在main函数创建这个继承自QMainwindow的窗口类要注册过滤本地事件的类。
MainWindow w;
w.installNativeEventFilter(&w);
w.show();
本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。