C++ 在进入单独的函数之前强制更新 Qt GUI

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12410433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:15:42  来源:igfitidea点击:

Forcing the Qt GUI to update before entering a separate function

c++qtfunctionuser-interface

提问by zebra

This seems like it should be automatic, but apparently it's not. I have the following code:

这似乎应该是自动的,但显然不是。我有以下代码:

    ui.my_label->setText("Test 1...");
    ui.my_label->adjustSize();

    processThatTakesAbout30SecondsToFinish(files[0].toStdString());

    ui.my_label->setText("Finished.");
    ui.my_label->adjustSize();

What is happening is that I neversee "Test1...",as the GUI seems to hang until the following function completes, and I eventaully only see "Finished.".

发生的事情是,在以下功能完成之前,我从未看到"Test1...",GUI 似乎挂起,而我最终只看到“已完成。”。

How can I make sure the GUI is updating before it enters that function?
Thanks.

在进入该功能之前,如何确保 GUI 正在更新?
谢谢。

回答by Joachim Isaksson

You shuld be able to process the event queue before entering your code if you;

如果您这样做,您应该能够在输入代码之前处理事件队列;

#include <QApplication>

and, when you want to refresh your GUI, call;

并且,当您想刷新 GUI 时,请调用;

qApp->processEvents();

Note that it may be a good idea to let your long running process call that function now and then, to make your GUI feel more responsive.

请注意,让长时间运行的进程不时调用该函数可能是个好主意,以使您的 GUI 感觉更灵敏。

回答by Chris

If you don't care about your GUI being responsive during this time, then a call to my_label->repaint()would do the trick. Qt can't do anything automatically for you unless you yield to the event loop.

如果您不关心在此期间您的 GUI 是否有响应,那么调用my_label->repaint()就可以解决问题。除非您屈服于事件循环,否则 Qt 无法自动为您做任何事情。

For maximimum responsiveness you might consider running your process in a separate thread and use signal/slot connections (which are thread-safe by default) to signal to your main GUI thread when your processing is complete.

为了获得最大响应,您可以考虑在单独的线程中运行您的进程,并在处理完成时使用信号/插槽连接(默认情况下是线程安全的)向主 GUI 线程发送信号。

回答by Chuck Claunch

I just wanted to add that for me it took a combo of the two answers I saw here. So what worked for me was:

我只是想补充一点,它结合了我在这里看到的两个答案。所以对我有用的是:

ui.my_label->setText("Test 1...");
ui.my_label->adjustSize();

//! Both of these lines needed
ui.my_label->repaint();
qApp->processEvents();

processThatTakesAbout30SecondsToFinish(files[0].toStdString());

ui.my_label->setText("Finished.");
ui.my_label->adjustSize();

Hope this helps someone.

希望这可以帮助某人。

回答by Kemendil

Defining a function...

定义函数...

void YourClass::Update_Ui()
{
if(this->isEnabled())
    return;

this->repaint();
qApp->processEvents();
}

...like this and make sure thisis disabled (to prevent user actions) while you want to force an update of the uiwas the best solution for me.

...像这样并确保this已禁用(以防止用户操作),而您想强制更新ui对我来说是最好的解决方案。

Example how to use it inside a function (for example during a stack processing that takes lots of time):

如何在函数内部使用它的示例(例如在需要大量时间的堆栈处理期间):

this->setEnabled(false);
//Do whatever you want
Update_Ui();
//Do some other stuff
this->setEnabled(true);

This doesn't allow the user to disturb the processing by uiinteraction (it is disabled) and updates whenever Update_Ui();is called in the code and updates the whole ui, not just a chosen label or whatever. Note that this doesn't block signals fired by uielements.

这不允许用户通过ui交互来干扰处理(它被禁用)并Update_Ui();在代码中调用时更新并更新整个ui,而不仅仅是选择的标签或其他任何东西。请注意,这不会阻止ui元素触发的信号。