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

问题描述:

在部分代码中(如下所示),标签在之后更新为,下一行中的generate函数已完成工作。在开始生成开始工作之前,我需要更新标签。C++ Qt保留操作顺序:在移动之前更新QLabel

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的基础知识。我的程序直接退出,没有额外的线程活动。我的猜测到目前为止,Qt的线程正在做一些有趣的事情,但我不知道如何获得理想的结果。

使用Qt 4.8,Ubuntu 16.04,编译过程:qmake -project,qmake,make。使用Qt设计器生成的.ui文件,someLabel来自生成的ui _... h文件,myDialog与生成的.h文件和QDialog具有is-a关系。 func.generate_str()来自本地#include“...”和实例func。该程序的其他各个部分均可成功运行。

你有两个问题:

  1. 您的标签不更新为主线不能回到事件循环进入的generate_str()函数之前。

改变标签后,您可以砍解决此通过使用QApplication::processEvents()

  1. 你有一个函数调用需要几秒钟5和10之间的主线程上运行的一个GUI程序,这意味着您的应用程序将在此期间“冻结”。
  2. 对于这个问题,您可以考虑同时运行该功能,例如,与一个线程,或分散它在许多较小的步骤,让主线程完成其主要工作(事件处理),而它逐步走过的步骤

开始=“2”>
+0

我现在明白了,谢谢! –

UI操作通常不会同步完成。尝试在事件循环的下一次迭代中调度func.generate_str(),甚至稍后。像这样的东西可能会奏效:

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

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

+0

我得到这些错误:'错误:没有匹配函数调用'QTimer :: singleShot(int,myDialog :: generate_str():: )'' 做'QTimer :: singleShot(0,this,SLOT(func.generate_str()));'似乎使编译器很高兴,但generate_str不是一个插槽,并且我还需要一种方法来从generate_str函数获取返回结果,我不知道如何以这种格式执行操作。 –

+0

我也试过拖延:'std :: this_thread :: sleep_for(std :: chrono :: seconds(1));'这并没有解决问题。 –

+0

您需要让循环结束。在您看到更新之前,Sleeping将无助于执行您排队的UI更新,因为该循环运行需要完成。检查这个答案了如何使一个插槽:http://*.com/questions/8544665/qtimersingleshot-looks-for-the-specified-slot-in-the-given-objects-parent-c – dbv