响应USB接口为串口类型的拔插事件

16 篇文章 0 订阅

项目场景:

做了一个解析USB接口的GPS接收机报文的插件,界面如下:

由于,插件只有在整个软件打开时才会初始化,中途不会析构,那么使用过程中如果,GPS接收机拔出再插入另一接口,所有功能将失效,因为端口为自动解析的,并且是在初始化时,获取所有可用串口,如果想功能正常必须重启软件,肯定影响使用。

问题描述

基于项目背景,需要寻找一个响应USB接口拔插的事件。


解决方案:

直接在Widget类里使用nativeEvent方法即可。

GPSPositionWidget.h文件如下:

#ifndef GPSPositionWidget_H
#define GPSPositionWidget_H

#include <QWidget>

QT_BEGIN_NAMESPACE
	namespace Ui {class CGPSPositionWidget;}
QT_END_NAMESPACE

class CGPSPositionWidget
{
	Q_OBJECT

public:
	CGPSPositionWidget(QWidget *parent = 0);
	~CGPSPositionWidget();

public:

	/**
	* @fn  Initialize        
	* @brief 初始化窗体
	* @param 
	* @return 
	*/
	void Initialize();

protected:

	bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;//监控Windows系统事件(硬件热插拔);

private:
	Ui::CGPSPositionWidget* ui;
	QSerialPort *m_pserial;
};

#endif // GPSPositionWidget_H

 GPSPositionWidget.cpp如下:

#include "GPSPositionWidget.h"
#include "ui_GPSPositionWidget.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include "qdebug.h"
#include <windows.h>
#include "dbt.h"

CGPSPositionWidget::CGPSPositionWidget(QWidget *parent)
	: CustomWidget(parent)
	, m_pserial(NULL)
	, m_bIsShowPoint(false)
	, m_bIsSaveTra(false)
	, m_pGPSMapEventHandler(nullptr)
{
	ui = new Ui::CGPSPositionWidget();
	ui->setupUi(panel);
	setTitle(ConvertCharArrayToQString("GPS定位"));

	Initialize();
}

CGPSPositionWidget::~CGPSPositionWidget()
{
	delete ui;
	ui = nullptr;
}

void CGPSPositionWidget::Initialize()
{
	
	ui->portComboBox->clear();
	ui->baudComboBox->clear();
	ui->dataBitsComboBox->clear();
	ui->stopBitsComboBox->clear();
	ui->parityComboBox->clear();
	ui->flowControlComboBox->clear();
	ui->modeComboBox->clear();
	//状态栏清空
	ui->statusLabel->clear();
	//获取计算机上所有可用串口并添加到comBox中
	QList<QSerialPortInfo>  infos = QSerialPortInfo::availablePorts();
	if(infos.isEmpty())
	{
		ui->portComboBox->addItem(ConvertCharArrayToQString("无串口"));
		return;
	}
	else
	{
		m_pserial = new QSerialPort;
	}
	foreach (QSerialPortInfo info, infos) {
		ui->portComboBox->addItem(info.portName());
		qDebug() << info.portName();
	}

	//设置三种波特率
	QStringList strBaud;
	strBaud<<ConvertCharArrayToQString("4800")<<ConvertCharArrayToQString("9600")<<ConvertCharArrayToQString("115200");
	ui->baudComboBox->addItems(strBaud);
	ui->baudComboBox->setCurrentIndex(1);

	//设置四种数据位
	QStringList strData;
	strData<<ConvertCharArrayToQString("5")<<ConvertCharArrayToQString("6")<<ConvertCharArrayToQString("7")<<ConvertCharArrayToQString("8");
	ui->dataBitsComboBox->addItems(strData);
	ui->dataBitsComboBox->setCurrentIndex(3);

	//设置三种停止位
	QStringList strStop;
	strStop<<ConvertCharArrayToQString("1")<<ConvertCharArrayToQString("1.5")<<ConvertCharArrayToQString("2");
	ui->stopBitsComboBox->addItems(strStop);
	ui->stopBitsComboBox->setCurrentIndex(0);

	//设置五种校验位
	QStringList strParity;
	strParity<<ConvertCharArrayToQString("None")<<ConvertCharArrayToQString("Odd")<<ConvertCharArrayToQString("Even")<<ConvertCharArrayToQString("Mark")<<ConvertCharArrayToQString("Space");
	ui->parityComboBox->addItems(strParity);
	ui->parityComboBox->setCurrentIndex(0);

	//设置四种流控
	QStringList strFlowControl;
	strFlowControl<<ConvertCharArrayToQString("None")<<ConvertCharArrayToQString("Hardware")<<ConvertCharArrayToQString("Software");
	ui->flowControlComboBox->addItems(strFlowControl);
	ui->flowControlComboBox->setCurrentIndex(0);

	//设置三种定位模式
	QStringList strMode;
	strMode<<ConvertCharArrayToQString("推荐定位")<<ConvertCharArrayToQString("GPS定位")<<ConvertCharArrayToQString("北斗定位");
	ui->modeComboBox->addItems(strMode);
	ui->modeComboBox->setCurrentIndex(0);
}

bool CGPSPositionWidget::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;
					Initialize();
					ui->statusLabel->setText(ConvertCharArrayToQString("设备插入!"));
				}
				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;
                    //如果串口打开的过程中拔出先关闭串口
					if (m_pserial != NULL)
					{
						m_pserial->close();
					}
					//恢复设置功能
					ui->switchButton->setText(ConvertCharArrayToQString("打开串口"));
					Initialize();
					ui->statusLabel->setText(ConvertCharArrayToQString("设备拔出!"));
				}
				break;
			}
		default:
			break;
		}
	}

	return false;
}

注意:使用nativeEvent方法,.cpp文件里必须添加#include <windows.h>,#include "dbt.h"两个头文件。

ConvertCharArrayToQString()自定义格式转换方法。

 最终效果如下:

 

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值