繁体   English   中英

如何控制应该在GUI中绘制的QGridLayout中的小部件?

[英]How to control the Widgets in QGridLayout that should be painted in GUI?

在我的应用程序中,我有一个QGridLayout ,它覆盖了Window的大部分。 在其中,我添加了一系列QLineEditQLabel对象。 当前,当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); } 
  • 作为最后的选择,请使用QGraphicsSceneQGraphicsWidgetQGraphicsGridLayoutQGraphicsView UI。 场景图可能会更好地丢弃不必要的UI重绘。

首先。 您确定以正确的方式解决问题吗? 也许您会更喜欢QTableWidget? 它的单元格可以编辑,然后QTableWidget将负责为正在编辑的单元格创建和维护QLineEdit。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM