QT实时更新串口助手中的串口名称

问题及解决方案

当用USB在电脑上插拔,自制的简易串口助手中串口名称不会实时更新,因此为了实现更新串口名,这里记录一下实现过程

解决方案:将Windows的设备管理消息发送给QT进行处理(需要包含windows.h),自定义子类继承QWidget、QAbstractNativeEventFilter,并在子类中实现QAbstractNativeEventFilter类中的纯虚函数bool nativeEventFilter()
如果使用重写bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)的方法,并不会接收到来的Windows的消息,nativeEventbug
引用:https://stackoverflow.com/questions/26652783/qtnativeevent-calls

First: you don’t need to call nativeEvent method directly. It is a callback that is called by Qt. You may override it.

Second. There are known bugs in Qt5 with processing nativeEvent. So be careful with it. But, as I know, there are problemd only with native child widgets.

Second. There are known bugs in Qt5 with processing nativeEvent. So be careful with it. But, as I know, there are problemd only with native child widgets.

Third. Solution: create your own QAbstractNativeEventFilter. Hint, how to use it (because it is not well-documented):

QAbstractEventDispatcher::instance()->installNativeEventFilter(yourFilter);

源代码

myeventfilter.h的内容如下:

#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H

#include <QAbstractNativeEventFilter>
#include <QWidget>

class MyNativeFilter : public QWidget, public QAbstractNativeEventFilter
{
    Q_OBJECT
public:
    MyNativeFilter();
    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
signals:
    void DeviceChanged();

};

#endif // MYEVENTFILTER_H

这里继承QWidget是为了使用信号与槽机制,添加了宏Q_OBJECT需要重新Build(构建)一下项目,否则会出现错误:error: undefined reference to vtable for`。有关QAbstractNativeEventFilter的介绍,参照官方文档:https://doc.qt.io/qt-5/qabstractnativeeventfilter.html

myeventfilter.cpp的内容如下,必须需要包含头文件windows.hdbt.h

#include "myeventfilter.h"
#include <windows.h>
#include <dbt.h>

MyNativeFilter::MyNativeFilter()
{

}

bool MyNativeFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(eventType);
    Q_UNUSED(result);
    MSG *msg = static_cast<MSG*>(message);
    if(msg->message == WM_DEVICECHANGE)
    {
        if(msg->wParam == DBT_DEVICEARRIVAL ||
                msg->wParam == DBT_DEVICEREMOVECOMPLETE) //新增了设备或移除了设备
        {
            emit DeviceChanged();	//发出设备修改的信号
        }

    }

    return false;
}

MSG是在winuser.h中声明的结构体

typedef struct tagMSG {
  HWND   hwnd;
  UINT   message;
  WPARAM wParam;
  LPARAM lParam;
  DWORD  time;
  POINT  pt;
  DWORD  lPrivate;
} MSG, *PMSG, *NPMSG, *LPMSG;

这里只说明message和wParam两个结构体成员

  • message:类型:UINT,消息的标识符。 应用程序只能使用低字;高字由系统保留。
  • wParam:类型WPARAM,关于消息的附加信息。 确切含义取决于消息成员的值。

message的取值:Wm/设备管理消息

wParam的取值:WM_DEVICECHANGE 消息 (Winuser.h) - Win32 apps | Microsoft Learn

微软官网文档:消息队列

官方文档上写到:在重新实现此功能时,如果您想过滤掉消息,即停止进一步处理,请返回true;否则返回false。因为这里需要进一步处理msg,所以这里返回false。

In your reimplementation of this function, if you want to filter the message out, i.e. stop it being handled further, return true; otherwise return false.

使用方法

自定义类SerialPortWidget,在serialportidget.cpp中实现,serialportidget.cpp部分代码如下:

 
#include <QCoreApplication>
#include "myeventfilter.h"		//包含事件过滤器头文件


MyNativeFilter *nativefilter = new MyNativeFilter;
qApp->installNativeEventFilter(nativefilter);	//设置本地事件过滤器
												//qApp是一个宏,等价于QCoreApplication::instance()

//从MyNativeFilter类中发射出的信号DeviceChanged,在serialportidget.cpp中进行信号的处理
connect(nativefilter, &MyNativeFilter::DeviceChanged, [=]{
    if(serialport->isOpen())
        serialport->close();
    //获取串口信息,进行串口名刷新
    QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
    serialPortComboBox->clear();
    for (const QSerialPortInfo &info : infos)		//foreach遍历串口信息
        serialPortComboBox->addItem(info.portName());   //获取串口名
});

运行效果

在这里插入图片描述

参考链接:

https://stackoverflow.com/questions/26652783/qtnativeevent-calls
https://blog.csdn.net/zzzw0/article/details/104367345
https://blog.csdn.net/u010168781/article/details/105298677

  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一种跨平台的应用程序框架,可以用于开发各种类型的应用程序,包括串口助手Qt 5.12是Qt框架的一个版本,具有许多新的功能和改进。下面将使用文回答关于Qt 5.12串口助手的问题。 Qt 5.12串口助手是一个用于与串口通信的工具。它允许用户通过串口与其他设备进行数据交换。使用串口助手,用户可以发送和接收数据,并监视串口的状态。 Qt 5.12的串口助手具有用户友好的界面和丰富的功能。用户可以选择串口号、波特率、数据位、停止位和校验位等参数,并且可以自定义这些参数以满足特定的需求。用户可以通过打开和关闭串口连接来开始和结束通信。 在串口助手,用户可以输入要发送的数据,并通过点击发送按钮将其发送到串口。用户还可以接收从串口接收到的数据,并在界面上显示。这样,用户可以通过串口助手实时地查看和分析串口通信数据。 此外,Qt 5.12的串口助手还提供了诸如自动发送、数据保存、接收数据打印和数据清除等功能。用户可以设置自动发送功能,使串口助手自动按照特定的时间间隔发送数据。用户还可以将接收到的数据保存到本地文件,以便后续分析和使用。 总的来说,Qt 5.12的串口助手是一个功能强大而易于使用的工具,可以帮助用户与串口通信并监视数据的发送和接收。无论是用于嵌入式系统的开发还是进行串口调试,Qt 5.12的串口助手都能提供方便快捷的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值