C++ Qt 保留操作顺序:在继续之前更新 QLabel

C++ Qt preserve order of operation: update QLabel before moving on

在代码的一部分(如下所示)中,标签更新为文本 下一行的生成函数完成工作后。我需要在开始生成开始工作之前更新标签。

void myDialog::my_custom_slot()
{
   emit someLabel->setVisible(true);
   emit someLabel->setText("Some Text...");

   string result = func.generate_str(); // operation takes 5 to 10 second
}

我仍在学习 Qt 的基础知识。我的程序是 quit 直接的,没有额外的线程活动。到目前为止,我的猜测是 Qt 的线程正在做一些有趣的事情,但我不确定如何获得所需的结果。

使用Qt 4.8,Ubuntu16.04,编译过程:qmake -projectqmakemake。使用Qt designer 生成的.ui 文件,someLabel 来自于生成的ui_...h 文件,而myDialog 与生成的.h 文件和QDialog 具有is-a 关系。 func.generate_str() 来自本地#include "..." 和实例函数。该程序的所有其他部分都成功运行。

UI 操作通常不会同步完成。尝试在事件循环的下一次迭代中安排 func.generate_str(),甚至更晚一些。这样的事情可能会奏效:

QTimer::singleShot(0, [&]{ func.generate_str(); });

0 是 0 毫秒,这意味着下一个 运行 循环迭代。第二个参数的有趣语法是 C++ lambda (C++11 起)。

你有两个问题:

  1. 您的标签未更新,因为主线程在进入 generate_str() 函数之前无法返回事件循环。

您可以在更改标签后使用 QApplication::processEvents() 解决此问题

  1. 您在 GUI 程序的主线程上有一个需要 5 到 10 秒 运行 的函数调用,这意味着您的应用程序在此期间将 "frozen"。

对于这个问题,您可以同时考虑 运行 函数,例如用一个线程,或者将它分成许多更小的步骤,让主线程在一个接一个地执行这些步骤的同时完成它的主要工作(事件处理)