一、目的
我想实现qt串口的实时检测(热拔插): Qt串口通信的时候(串口已打开且已经连接),这时usb(串口)意外被拔掉了,或者其他情况要怎样才能检测到,并给出提示呢。
看下面的代码,举一个例子。/**/注释中的是他提供给大家的调试代码。
connect(serialPort, &QSerialPort::errorOccurred, this, &Widget::handleSerialError);
/*这行代码的作用是将 QSerialPort::errorOccurred 信号与 CRunThread::handleSerialError 槽函数连接起来。当串口发生错误时,信号会被触发,槽函数会被自动调用以处理该错误。*/
/*需要测试槽函数是否连接成功,可使用此测试
bool isConnected = connect(serialPort, &QSerialPort::errorOccurred, this, &Widget::handleSerialError);
if (!isConnected) {
qDebug() << "信号连接失败!";
} else {
qDebug() << "信号连接成功!";
}
*/
void Widget::handleSerialError(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError) {
// 如果发生了资源错误,执行以下代码
serialPort->close();
QMessageBox::critical(this, tr("Error"), tr("串口连接中断,请检查连接!"));
}
}
/*
void Widget::handleSerialError(QSerialPort::SerialPortError error)
{
qDebug() << "错误发生,错误代码:" << error;
if (error == QSerialPort::ResourceError) {
qDebug() << "检测到资源错误,关闭串口";
serialPort->close();
QMessageBox::critical(this, tr("Error"), tr("串口连接中断,请检查连接!"));
} else {
qDebug() << "非资源错误类型,错误代码:" << error;
}
}
*/
二、QSerialPort::SerialPortError的枚举类型
上面的代码对吗,对也不对,怎么说呢,我们看这个处理函数中的error,他是一个枚举类型中的错误类型:它可以细分为10多种:
QSerialPort::NoError
:没有发生错误。正常状态。QSerialPort::DeviceNotFoundError
:无法找到串口设备。这可能是因为设备未连接、设备名称错误,或者设备在使用时被移除了。QSerialPort::PermissionError
:没有足够的权限访问设备。这通常出现在尝试打开串口设备时,没有相应的权限(例如,没有管理员权限或设备被其他程序占用)。QSerialPort::OpenError
:无法打开设备。可能是因为设备被其他应用程序占用,或者设备已经在其他地方打开了。QSerialPort::ParityError
:校验错误。数据传输中发生了校验错误,通常与串口的奇偶校验配置有关。QSerialPort::FramingError
:帧错误。通常表示串口设备在接收数据时帧出错,可能是由于硬件问题或串口配置不匹配。QSerialPort::BreakConditionError
:串口中断错误。串口接收到中断信号时发生错误。QSerialPort::WriteError
:写入数据时发生错误。可能是因为写入操作失败或设备无法接受数据。QSerialPort::ReadError
:读取数据时发生错误。可能是因为读取操作失败或设备无法发送数据。QSerialPort::ResourceError
:资源错误。通常在设备突然断开连接时发生,例如拔掉 USB 串口设备。这是一个常见的设备断开错误。QSerialPort::UnsupportedOperationError
:操作不支持。试图执行当前设备不支持的操作时发生。QSerialPort::UnknownError
: 未知错误。发生了未知错误,可能是由系统错误或未捕获的异常引起的。QSerialPort::TimeoutError
:操作超时。串口操作未在预期时间内完成,可能是因为设备响应缓慢或者通信线路不稳定。QSerialPort::NotOpenError
:串口未打开。试图执行需要打开串口的操作时,串口却未处于打开状态。
.
.
三、具体场景具体应用
如果上述代码中笼统的都认为是错误,都在槽函数中关闭了串口,那么显然是不合理的。
.
举例,在串口未插入时打开了串口软件,这是串口是没有可选择的com的,这是你依然点击了,“打开串口”这个按钮,那么这个error会给你返回NotOpenError,
现在了解了细分的错误类型,那么你应该知道该怎么处理了......
.
在实际应用中,您可以根据需要处理特定的错误类型。例如,在串口通信中,您可以通过 error == QSerialPort::ResourceError
来判断是否发生了该错误并采取相应措施。
.
回到最初我想做的是,在Qt串口通信的时候(串口已打开且已经连接),这时usb(串口)意外被拔掉了,则给出提示呢
void Widget::handleSerialError(QSerialPort::SerialPortError error)
{
/*仅处理串口打开时发生的错误*/
if(serialPort->isOpen())
{
/*处理串口的权限错误或设备断开错误*/
if (error == QSerialPort::ResourceError ||error == QSerialPort::PermissionError ||
error == QSerialPort::DeviceNotFoundError ||error == QSerialPort::NotOpenError) {
qDebug() << "检测到严重错误,关闭串口";
serialPort->close();
//串口关闭后的对应操作
setLED(ui->LED_label, 0, 16);//串口状态指示灯-初始灰
ui->OpenSerialPort_pushButton->setText(tr("打开串口"));
ui->SerialPort_comboBox->setEnabled(true);// 让端口号下拉框可选
QMessageBox::critical(this, tr("Error"), tr("串口连接中断或权限错误,请检查连接和权限!"));
on_RefreshSerialPort_pushButton_clicked();//刷新串口
ui->MTextlabel->setText("错误,串口关闭!");
}else if (error == QSerialPort::NoError) {
/*NoError 情况下,不做任何操作*/
qDebug() << "没有错误发生";
} else {
qDebug() << "非资源错误类型,错误代码:" << error;
}
}
}
.
.
四、其他
若是使用上面的代码发生错误,可以尝试在connect前面加上此代码
qRegisterMetaType<QSerialPort::SerialPortError>("CRunThread");
这行代码的作用是注册 QSerialPort::SerialPortError
类型,使其可以在信号和槽的连接中被安全地传递,尤其是在跨线程通信的情况下。
具体说明:
qRegisterMetaType<T>
:这是一个Qt的模板函数,用来注册用户自定义的类型或者是某些没有自动注册的Qt类型,以便这些类型可以用于信号和槽的连接,特别是在跨线程通信时。QSerialPort::SerialPortError
:这是QSerialPort
中定义的枚举类型,用于表示不同的串口错误。"CRunThread"
:这是一个字符串,通常用于标识特定的注册类型。这在代码中用于说明该注册是在CRunThread
类中执行的,不过实际上这个字符串参数主要是为了给注册的类型一个识别标志。这里它只是一个任意的标识符,可以是任何有效的字符串,甚至不需要完全匹配类名。更重要的是实际类型(QSerialPort::SerialPortError
)本身的注册。