为什么打开串口的提示窗口都提示两遍

问题根源分析

在 ModbusRTU 类中,initializePort 方法会在打开串口时通过 emit portOpened(true) 发送信号。如果 MainWindow 类中同时通过以下两种方式触发弹窗,就会导致提示重复:

  1. 直接弹窗:在按钮点击事件中手动调用 QMessageBox::information

  2. 信号槽弹窗:将 portOpened 信号连接到另一个显示弹窗的槽函数。


解决方案

1. 移除冗余弹窗逻辑

修改 MainWindow::on_btnOpenPort_4_clicked,仅保留一种提示方式:

cpp

复制

void MainWindow::on_btnOpenPort_4_clicked() {
    // 如果已存在实例,先释放资源
    if (modbusRTU) {
        delete modbusRTU;
        modbusRTU = nullptr;
    }

    // 配置串口参数
    QString portName = "COM15";
    uint32_t baudRate = 115200;
    uint8_t deviceAddress = 0x01;

    // 创建新实例并配置参数
    modbusRTU = new ModbusRTU(this);
    if (modbusRTU->initializePort(portName, baudRate)) {
        modbusRTU->setDeviceAddress(deviceAddress);
        modbusRTU->clearBuffers();

        // 禁用 "打开串口" 按钮,防止重复打开
        ui->btnOpenPort_4->setEnabled(false);

        // 直接通过信号触发弹窗,或在此处弹窗,但不要两者同时存在
        // QMessageBox::information(this, "Success", "Port opened successfully."); // 注释掉此行
    } else {
        QMessageBox::critical(this, "Error", "Failed to open serial port.");
        delete modbusRTU;
        modbusRTU = nullptr;
    }
}
2. 统一使用信号槽机制

在 MainWindow 构造函数中连接 portOpened 信号到弹窗槽函数,并移除按钮事件中的手动弹窗

cpp

复制

// MainWindow 构造函数
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    // 连接 ModbusRTU 的信号到 MainWindow 的槽
    connect(modbusRTU, &ModbusRTU::portOpened, this, &MainWindow::handlePortOpened);
}

// 槽函数处理串口打开成功
void MainWindow::handlePortOpened(bool success) {
    if (success) {
        QMessageBox::information(this, "Success", "串口已成功打开");
    }
}
3. 确保信号唯一性

每次创建新的 ModbusRTU 对象时,断开旧信号连接,避免重复触发:

cpp

复制

void MainWindow::on_btnOpenPort_4_clicked() {
    if (modbusRTU) {
        disconnect(modbusRTU, &ModbusRTU::portOpened, this, &MainWindow::handlePortOpened); // 断开旧连接
        delete modbusRTU;
        modbusRTU = nullptr;
    }

    modbusRTU = new ModbusRTU(this);
    connect(modbusRTU, &ModbusRTU::portOpened, this, &MainWindow::handlePortOpened); // 连接新信号

    // ...其他代码...
}

关键代码解释

  1. 信号与槽分离

    • 将弹窗逻辑统一放在 handlePortOpened 槽函数中,避免在按钮点击事件中直接弹窗。

    • 通过 connect/disconnect 管理信号连接,防止旧对象触发无效弹窗。

  2. 资源管理优化

    • 在删除 modbusRTU 前断开信号连接,避免野指针导致崩溃。

  3. 防止重复操作

    • 禁用打开按钮 (ui->btnOpenPort_4->setEnabled(false)) 防止用户多次点击。


验证步骤

  1. 运行程序并点击打开串口按钮

    • 确认弹窗仅出现一次。

  2. 模拟串口打开失败

    • 占用 COM15 或拔掉设备,观察错误提示是否唯一。

  3. 多次打开/关闭串口

    • 确保每次操作后弹窗次数正常。


通过以上修改,可彻底解决弹窗重复问题,并提升代码健壮性

你可能感兴趣的:(软件报错问题,命令模式)