在我的应用程序中,我有一个QGridLayout
,它涵盖了大部分Window
。我在其中添加了QLineEdit
和QLabel
对象的序列。当前,当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);
}
不得已时,使用
QGraphicsScene
,QGraphicsWidget
,QGraphicsGridLayout
和QGraphicsView
中继UI。场景图可能会更好地丢弃不必要的UI重绘。关于c++ - 如何控制应该在GUI中绘制的QGridLayout中的小部件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15295009/