Windows下QT实现串口热插拔
时间: 2024-05-07 21:21:36 浏览: 170
在Windows下实现串口热插拔,需要通过Windows API来监测串口的插拔事件并做出相应处理。下面是一个使用QT实现串口热插拔的示例代码:
```c++
#include <QCoreApplication>
#include <QtSerialPort/QSerialPort>
#include <QObject>
#include <QDebug>
#include <windows.h>
//定义一个继承自QObject的类,用于处理串口插拔事件
class SerialPortWatcher : public QObject
{
Q_OBJECT
public:
SerialPortWatcher(QObject *parent = nullptr) : QObject(parent) {}
signals:
void serialPortAdded(QString portName); //定义串口插入信号
void serialPortRemoved(QString portName); //定义串口拔出信号
public slots:
void checkSerialPorts() //检测串口列表
{
QStringList currentSerialPortList = getSerialPortList(); //获取当前串口列表
for (int i = 0; i < currentSerialPortList.size(); i++)
{
if (!m_serialPortList.contains(currentSerialPortList[i])) //如果当前串口列表中有新串口
{
emit serialPortAdded(currentSerialPortList[i]); //发射串口插入信号
}
}
for (int i = 0; i < m_serialPortList.size(); i++)
{
if (!currentSerialPortList.contains(m_serialPortList[i])) //如果当前串口列表中有串口被拔出
{
emit serialPortRemoved(m_serialPortList[i]); //发射串口拔出信号
}
}
m_serialPortList = currentSerialPortList; //更新串口列表
}
private:
QStringList getSerialPortList() //获取当前串口列表
{
QStringList serialPortList;
for (int i = 1; i <= 255; i++)
{
QString portName = QString("COM%1").arg(i);
HANDLE handle = CreateFileA(portName.toStdString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
CloseHandle(handle);
serialPortList.append(portName);
}
}
return serialPortList;
}
QStringList m_serialPortList; //保存当前串口列表
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSerialPort serialPort;
SerialPortWatcher *serialPortWatcher = new SerialPortWatcher(&a); //创建串口监测对象
QObject::connect(serialPortWatcher, &SerialPortWatcher::serialPortAdded, [&serialPort](QString portName)
{
qDebug() << "Serial Port Added: " << portName;
if (!serialPort.isOpen()) //如果串口没有打开,就打开新插入的串口
{
serialPort.setPortName(portName);
serialPort.setBaudRate(QSerialPort::Baud115200);
serialPort.setParity(QSerialPort::NoParity);
serialPort.setDataBits(QSerialPort::Data8);
serialPort.setStopBits(QSerialPort::OneStop);
if (serialPort.open(QIODevice::ReadWrite))
{
qDebug() << "Serial Port Opened: " << portName;
}
}
});
QObject::connect(serialPortWatcher, &SerialPortWatcher::serialPortRemoved, [&serialPort](QString portName)
{
qDebug() << "Serial Port Removed: " << portName;
if (serialPort.isOpen() && serialPort.portName() == portName) //如果串口已经打开,并且是当前拔出的串口,就关闭串口
{
serialPort.close();
qDebug() << "Serial Port Closed: " << portName;
}
});
QTimer *timer = new QTimer(&a);
timer->setInterval(1000); //设置定时器时间间隔为1秒
timer->start();
QObject::connect(timer, &QTimer::timeout, serialPortWatcher, &SerialPortWatcher::checkSerialPorts); //连接定时器与串口监测对象的检测方法
return a.exec();
}
#include "main.moc"
```
上述代码中,我们创建了一个继承自QObject的类SerialPortWatcher,通过Windows API获取当前串口列表,并定时检测串口列表的变化,如果有串口插入或拔出,就发射相应的信号。在主函数中,我们连接SerialPortWatcher的信号与串口打开和关闭的槽函数,实现自动打开和关闭串口。最后,我们启动事件循环,定时检测串口列表的变化。
阅读全文