在我的应用程序中,我有一个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.
我希望我能让这个问题变得简单易懂。
答案 0 :(得分:3)
我知道您不想丢弃您的代码。我会尝试其中一种,从最简单的方法开始:
您使用的是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重绘。
答案 1 :(得分:1)
首先。您确定以正确的方式解决问题吗?也许你会对QTableWidget更开心?它的单元格可以编辑,然后QTableWidget将负责为正在编辑的单元格创建和维护QLineEdit。