QGraphicsScene一直在调用QGraphicsItem绘制事件

QGraphicsScene is calling QGraphicsItem paint event all the time

本文关键字:绘制 事件 QGraphicsItem 调用 一直 QGraphicsScene      更新时间:2023-10-16

我有一个QWidget,它包含一个包含多个项目的QGraphicsScene。其中一些项目是QGraphicsRectItem s和子类QGraphicsItem s。当场景中只有QGraphicsRectItem s时,应用程序的性能良好,处理器使用率正常,在0%-10%之间。但是,当我将QGraphicsItem添加到场景中时,绘制事件总是被调用,这使得处理器的使用率提高到50%-70%,有时应用程序会被冻结。

当我将QGraphicsView视图更新模式设置为QGraphicsView::NoViewportUpdate时,QGraphicsItems和QGraphicsReviewItems的处理器使用情况都很好,但当视图更新模式设为QGraphicsIView::FullViewportUpdate、QGraphicsView::MinimalViewportUpdate或QGraphicsIview::BoundingRectViewportUpdate,则在循环中调用QGraphicsItem中的绘制事件,即使没有对场景进行修改。

这是我创建QGraphicsScene的方式,QGrahicsView是这样的。

scene = new QGraphicsScene();
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
scene->setSceneRect(0, 0, 470, 720);
view = new QGraphicsView(scene);
view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    
view->setMouseTracking(true);

子类化的QGraphicsItem是这样的:

MyItem::MyItem(QGraphicsItem *parent)
: QGraphicsItem(parent),
  mIsHover(false), mIsSelected(false)
{
    pixmapItem1 = new QGraphicsPixmapItem(this);
    pixmapItem2 = new QGraphicsPixmapItem(this);
    textItem = new QGraphicsTextItem(this);
    pixmapItem1->setParentItem(this);
    pixmapItem2->setParentItem(this);
    textItem->setParentItem(this);
    textItem->setTextWidth(60);
    this->setAcceptTouchEvents(true);
    this->setAcceptDrops(true);
    this->setAcceptHoverEvents(true);
    this->setAcceptedMouseButtons(Qt::LeftButton);  
    this->setFlag(QGraphicsItem::ItemIsSelectable);
    this->setFlag(QGraphicsItem::ItemIsMovable);
    this->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
    this->setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
 }
 QRectF MyItem::boundingRect() const
 {
       QRectF rect = this->childrenBoundingRect();
       return rect;
  }
  void MyItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*  opt,QWidget* wdgt)
  {
        qDebug() << "-> MyItem::pain()";
        painter->setClipRect(this->boundingRect());
        if(this->mIsHover || this->mIsSelected){
           painter->setBrush(QColor(Qt::green));
           painter->setPen(Qt::black);
           painter->drawRect(this->boundingRect());
        }else{
           painter->setBrush(Qt::transparent);
           painter->setPen(Qt::NoPen);
           painter->drawRect(this->boundingRect());
        }
   }
   void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent*)
   {
       qDebug()  << Q_FUNC_INFO;
       this->mIsHover = true;
       this->update();
   }
   void MyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent*)
   {
       qDebug() << Q_FUNC_INFO;
       this->mIsHover = false;
       this->update();
   }

因此,问题是,我如何才能使绘制事件仅在场景中或场景中的任何对象中有任何修改时才被调用,而不是QGraphicsScene一直在调用QGraphicsItem绘制事件?

您可以使用缓存:

// Put this in the constructor of your QGraphicsItem
setCacheMode( QGraphicsItem::DeviceCoordinateCache );
// or
setCacheMode( QGraphicsItem::ItemCoordinateCache);