在我的应用程序中,我有一个QGridLayout,它涵盖了大部分Window。我在其中添加了QLineEditQLabel对象的序列。当前,当QLineEdit对象数> 500和&QLabel对象数> 500时,GUI显着变慢,并且对于较大的值无法正常运行。同样,这些小部件中的大多数在窗口中都不可见,需要滚动它们才能查看。
由于我在widgets中添加了很多grid layout(通过在循环后循环并调用repaint),绘画需要花费很多时间。
因此,我对解决方案有一个想法,即使将我的widgets添加到Grid Layout中,也不是每个人都被涂上颜色。我想要一个rectangle,其中所有widgets都被绘制,并且只要滚动窗口,矩形的坐标就会更新。但是我不知道该怎么做。所以我想知道有可能这样做吗?
如果可能的话,请添加一小段示例代码,以便我了解如何实现该代码。
谢谢。

更新:添加一张图像来描绘场景。

Black Rectangle = QGridLayout say myGid.

Red Rectangle = Bounding Rectangle which is approximately same size as Main Window of my Application.

Green Rectangle = Widgets in myGrid.


Green Rectangle filled with yellow = Widgets shown in Main Window(仅应将这些小部件视为调用repaint的对象),其余未填充的矩形是myGrid中存在的小部件,但不视为调用repaint的部件。
因此,当我在主应用程序中滚动时,red rectangle的坐标将被更新,所有widgets bounded by it are considered for repaint.
希望我使问题简单易懂。

最佳答案

我了解您不想丢弃您的代码。我会尝试其中的一种,从最简单的方法开始:


您使用的是QScrollArea还是使用滚动条进行模拟? QScrollArea可能已经将绘画事件丢弃给不在视口中的子代小部件。在屏幕外组装网格。否则,每次添加新的小部件时,Qt都会重新计算并重新绘制布局。 (Here is a complete example。)

QWidget* widget = new QWidget(); // This is an invisible widget.

for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
        QLineEdit* lineEdit = new QLineEdit();
        lineEdit->setText(QString("I am the line edit at (%1, %2)").arg(i).arg(j));
        layout->addWidget(lineEdit, i, j);
        if (j % 10 == 0) {
            // Do not block the UI thread while the UI is being assembled.
            qApp->processEvents();
        }
    }
}

// The layout will be calculated only once, here:

scrollArea->setWidget(widget);
widget->show();

如果这不起作用,请创建一个event filter,该参考具有可见矩形的引用。事件过滤是一种有用的技术,您可以拦截针对一个或多个窗口小部件的事件,并确定在处理事件之前是否应将其丢弃。

在您的情况下,当您拦截QPaintEvent时,请检查目标小部件是否与可见矩形相交。如果确实如此,请将事件传递到目标小部件。如果不是,则放弃该事件。

我不知道如何滚动UI的细节,因此我将计算可见矩形的工作交给了您。事件过滤器代码将是这样的。

 bool MyClass::eventFilter(QObject *obj, QEvent *event)
 {
    if (event->type() == QEvent::Paint) {
        if (QWidget* widget = qobject_cast<QWidget*>(object)) {
            QRect visibleRectangle = somehowGetVisibleRectangle();
            if (visibleRectangle.intersects(widget->geometry())) {
                return false;
            } else {
                // Returning true means "drop this event."
                return true;
            }
        }
    }

    // Assuming MyClass extends QWidget. Adjust as necessary.
    return QWidget::eventFilter(obj, event);
 }

不得已时,使用QGraphicsSceneQGraphicsWidgetQGraphicsGridLayoutQGraphicsView中继UI。场景图可能会更好地丢弃不必要的UI重绘。

关于c++ - 如何控制应该在GUI中绘制的QGridLayout中的小部件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15295009/

10-12 21:33