QWidget不显示QLabel

时间:2018-02-26 19:00:34

标签: c++ qt

我有一个QWidget,我想在另一个QWidget的顶部使用Dialog。

我想要做的是一个简单的“请等待yadda yadda ...”对话框,没有按钮。

代码部分如下:

void NewWindow::on_combobox_New_currentIndexChanged(int index) //slot function
{
    QWidget* box = new QWidget();
    box->setWindowModality(Qt::ApplicationModal);
    box->setWindowTitle("Wait...");

    QHBoxLayout* layout = new QHBoxLayout();
    box->setLayout(layout);
    QLabel* lbl = new QLabel();
    lbl->setText("Loading...");
    layout->addWidget(lbl);

    box->show();


    for (int var = 0; var < st.size(); ++var)
    {
        //Some heavy lifting here
    }

    box->close();
}

通常情况下,我希望此对话框显示正确的文本,并在循环结束后消失。实际上它也是这样,但有一点不同:标签不显示。小部件看起来是空的。然后消失。

QWidget label not displaying

如果我将代码复制到另一个区域(例如,复制到MainWindow构造函数),它会正确显示,并显示消息。

QWidget label displaying properly

我感觉循环阻止了绘制操作,但是小部件本身也应该丢失。为什么只有标签才能让我望而却步。

感谢您的任何见解。

1 个答案:

答案 0 :(得分:6)

由于您在QObject插槽中创建并显示此小部件,然后在从插槽返回之前关闭小部件,在Qt执行所有指令的过程中,最后一个是{{1}因此,小部件从视图中消失。

在您的插槽下方,Qt正在事件循环中运行。由于控制永远不会返回到事件循环,因此Qt永远不会有机会渲染您要求的图形。

当你创建小部件,添加标签等时,你实际上是在事件循环中注册了一堆命令,这些命令只会在以后处理。

如果您希望Qt呈现您在插槽中所做的任何更改,则在返回事件循环之前,您必须致电processEvents

如果不这样做,您将无法看到这些更改,直到控件传回Qt事件循环

所以这里发生的事情是,因为你在插槽末端关闭小部件,Qt将创建小部件,呈现其内容,然后立即关闭它,你什么也看不见。

这样做的原因是,Qt可以对可见内容进行计算,不会对其呈现的内容进行计算等,并且只决定绘制必要的内容。

如果它只是立即呈现所有内容,而不是等待控制权返回它,那么它可以处理下一批更新&#34;,它可能会非常低效。

因此,您需要将close放入回调广告位。

processEvents

至于为什么窗口小部件窗口出现而不是内容,这很可能是因为在创建窗口小部件时Qt向窗口管理器发送消息(在本例中为MS Windows),这将创建Qt可以呈现的窗口它的内容。

所以你看到Windows的结果为Qt创建了一个新窗口,但是在该窗口本身的Qt绘画中没有任何内容。