[英]How to control the Widgets in QGridLayout that should be painted in GUI?
在我的应用程序中,我有一个QGridLayout
,它覆盖了Window
的大部分。 在其中,我添加了一系列QLineEdit
和QLabel
对象。 当前,当QLineEdit
对象的数量> 500 && QLabel
对象的数量> 500时, GUI
非常慢,并且对于较大的值,无法正常运行。 同样,这些小部件中的大多数在窗口中都不可见,需要滚动它们才能查看。 由于我在grid layout
添加了许多widgets
(通过循环并在循环后调用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.
的widgets bounded by it are considered for repaint.
希望我使问题简单易懂。
我了解您不想丢弃您的代码。 我会尝试其中的一种,从最简单的方法开始:
您正在使用QScrollArea
还是使用滚动条对其进行仿真? QScrollArea
可能已经将绘画事件丢弃到不在视口中的子窗口小部件。 在屏幕外组装网格。 否则,每次添加新的小部件时,Qt都会重新计算并重新绘制布局。 ( 这是一个完整的示例 。)
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();
如果这样不起作用,请创建一个事件过滤器 ,该事件过滤器的可见矩形引用为。 事件过滤是一种有用的技术,您可以拦截针对一个或多个窗口小部件的事件,并决定在处理事件之前是否应将其丢弃。
在您的情况下,当您拦截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重绘。
首先。 您确定以正确的方式解决问题吗? 也许您会更喜欢QTableWidget? 它的单元格可以编辑,然后QTableWidget将负责为正在编辑的单元格创建和维护QLineEdit。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.