在Qt中创建的GUI滞后(由QTime验证)

lag in GUI created in Qt (verified by QTime)

本文关键字:QTime 验证 滞后 GUI Qt 创建      更新时间:2023-10-16

我在Qt中有一个GUI C++ Class,它有一个SLOT,可以在QGridLayout中添加文本框和标签的数组。数组是正方形的,取决于变量,例如 n .即,如果n == 10,那么QGridLayout中有10x10 QTextboxQLabel。基本上,当用户按下"增加"按钮时,n的值将增加1,因此QTextboxQLabel是在SLOT中创建的,并在QGridLayout中添加。当n的值15 需要 1-2才能更新 GUI。但是,当我在该SLOT中使用QTime时,它向我显示执行该SLOT的实际时间约为 100毫秒。在调试模式下,我观察到QDebug用于打印经过的时间,即使 GUI 没有完全更新为更高的 n 值。我想知道为什么会有这么多延迟以及执行该SLOT后正在运行的内容,以便我可以测量相同的时间。我希望我把自己说清楚了。如果您无法理解我的问题,请告诉我。谢谢。

实际上,我现在没有确切的代码。因此,我创建了一个示例代码,突出显示了代码的逻辑。请忽略任何语法错误,因为我已尽快准备好。对不起,:(所以这是代码片段:

Class A
{
private:
    int n;
    QList <QLabel *> *labelList;
    QList <QTextEdit *> *textList;
    QGridLayout *inp;
    public slots:
        updateGUI();
}
A::updateGUI()
{
    QTime t;
    t.start();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
                            int even = j%2;
            QLabel *tempLab = new QLabel();
            //some stuff for initialisation of the QLabel
            QTextEdit *tempText = new QTextEdit();
            //some stuff for initialisation of the QTextEdit
            labelList->append(tempLab);
            textList->append(tempText);
                            if(even == 0)
                inp->AddWidget(tempLab, i, j, 5, 5, Qt::AlignCenter);
            else
                                inp->AddWidget(tempText, i, j, 5, 5, Qt::AlignCenter);
        }
    }
    QDebug("%d", t.elapsed());
}

PS:QTime tobj.start()SLOT的第一行,QDebug("%d", tobj.elapsed())SLOT的最后一行!

在小组件上执行批量更新时,请关闭 updatesEnabled 属性。这会阻止在添加 (11*11-10*10( 新按钮时进行 21 次单独更新。

0.1s 延迟是因为您正在创建大量小部件,然后将它们添加到网格中(每次添加小部件时,显然有开销,其他单元格的尺寸必须随着事物的"随机"而更新(。

那么为什么计时器之后还要进一步延迟呢? 槽生成的所有绘制和调整大小事件现在都已放入事件队列中,该队列在槽执行时已停止。 插槽完成后,需要处理所有这些任务。

除了其他人所说的之外,你正在做的事情有两个根本性的缺陷:

  • 删除所有现有小部件以添加可能单个小部件。 我认为我不需要解释这是多么低效......
  • 如果您设法进入向用户显示网格中的 100 个文本框和标签的情况 - 您的 UI 已失败。 您需要想出一种更好的方法来允许用户与所有这些数据进行交互。

如果您发布一些具有相同问题的代码,这将非常有帮助。当您选择 n=10 然后 n=7 时,您的老虎机将如何反应?它会从布局中删除最后 3 个项目吗?如果您选择 n=7,然后选择 n=10,它会尝试只添加最后 3 行吗?是否有可能,您没有从布局中删除项目并尝试在现有项目上添加新项目?

如果是这样 - 那么您可以使用以下内容从布局中删除所有小部件:

QLayoutItem* item;
while ( ( item = %your_layout_name%->takeAt( 0 ) ) != NULL ){
    delete item->widget();
}
delete item;

或者你可以通过它的对象名称(或句柄,存储在QList QVector或其他东西中(删除小部件:

swLayout->removeWidget(myTextEdit);

上级:现在,我们有一些代码,您还需要清除标签列表和文本列表,如果我正确的话,它们存储句柄。然后,线条

inp->AddWidget(tempLab, i, j, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempText, i, j, 5, 5, Qt::AlignCenter);

尝试将 tempLab 小部件添加到高度和宽度为 5 的位置 (i,j( 布局 inp,然后您尝试将另一个小部件 tempText 添加到同一位置,这显然是错误的

接下来,循环本身不正确:

for(int i = 0; i < n; i++)
{
    for(int j = 0; j < n; j++)
    {

如果你做一个这样的循环,那么你将添加这样的小部件:

inp->AddWidget(tempLab, i, 0, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempLab, i, 1, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempLab, i, n, 5, 5, Qt::AlignCenter);

但是您将小部件的宽度和高度设置为 5,因此您需要以另一种方式添加小部件,否则它们将相互绘制:

inp->AddWidget(tempText, i*5, j*5, 5, 5, Qt::AlignCenter);