为什么我的 QT C++ 应用程序在收到指示时不更新事件例程内的按钮文本?

Mar*_*McC 0 c++ user-interface qt scope

我对 Qt Creator 非常陌生,并且有一个关于按钮文本更新没有在我期望的时间发生的原因的问题。下面是显示按钮事件的代码片段。该按钮启动另一个外部进程 (AVRDUDE),该进程依次读取通过 USB 连接的 Arduino 板的 EEPROM 的内容。然后数据被处理并显示在 UI 中。由于读取 EEPROM 的过程需要几秒钟才能执行,因此我想将调用此例程的 UI 按钮从“READ FROM EEPROM”更改为“READING !!” 在执行该例程期间。例程完成后,将按钮标签返回到“READ FROM EEPROM”。这是代码

void MainWindow::on_READ_FROM_EEPROM_clicked() // Read EEPROM into file "fromEEPROM.bin", then output values to UI
{
    ui->READ_FROM_EEPROM->setText("READING !!");
    call_AVRDUDE_read();
    int mBufferLength = 1024;                    // AVR 1K EEPROM space in 328p
    char mBuffer[mBufferLength];
    float fB[mBufferLength/4];
    QString filename = "fromEEPROM.bin";
    QFile mFile(filename);
    ui->fileCurrentlyDisplayed->setText(filename); // make this filename visable in UI
    if (mFile.exists())
    {
        if (mFile.open(QFile::ReadOnly))
            while (!mFile.atEnd())
                mFile.read(mBuffer,sizeof(mBuffer));
     mFile.close();
     memcpy(&fB, &mBuffer, mBufferLength);  // Next, take mBuffer array of chars and copy them into a float array format
     moveFloatArrayToGUI(fB);       // Fill in the tables in the GUI from this array of floats. Pass fB ARRAY to function
    }                               // that fills in UI
    ui->READ_FROM_EEPROM->setText("READ FROM EEPROM");
}
Run Code Online (Sandbox Code Playgroud)

除了第一行之外,例程中的所有内容都完全按照预期执行

ui->READ_FROM_EEPROM->setText("READING !!)"
Run Code Online (Sandbox Code Playgroud)

和最后一行

ui->READ_FROM_EEPROM->setText("READ FROM EEPROM");
Run Code Online (Sandbox Code Playgroud)

我在按钮文本中看到的只是例程执行之前、整个过程中和之后的 READ FROM EEPROM 标签。如果我更改最后一行的文本字符串,这个新文本将出现在 UI 按钮中。如果我注释掉最后一行,那么“READING !!” 将出现在 UI 按钮中,但仅在例程完成后。

我在这里期待的是“阅读!!” msg 在输入时立即显示,然后将发生耗时的 AVRDUDE 调用,然后按钮文本将恢复为 READ FROM EEPROM。我尝试 ui->READ_FROM_EEPROM->setText("READING !!)" 从一个单独的按钮执行,它立即更新从 EEPROM 按钮读取的数据,所以我很困惑为什么该行在输入时没有立即执行。我错过了什么和/或我做错了什么?问候,马克

Vit*_*tor 5

仅当代码到达事件循环时,UI 才会更新,直到应用程序返回时才会发生这种情况。您可以通过在 UI 更新后调用来强制事件处理QCoreApplication::processEvents();,但推荐的方法是将阻塞代码推送到另一个线程并使用信号/槽来更新您的 UI。请参阅https://doc.qt.io/archives/qq/qq27-responsive-guis.html#manualeventprocessing以供参考。这篇文章很旧,但仍然有效。