QGraphicsScene все время вызывает событие рисования QGraphicsItem

У меня есть QWidget, который держит QGraphicsScene с несколькими предметами. Некоторые из этих элементов относятся к QGraphicsRectItem и относятся к QGraphicsItem подклассам. Когда в сцене только QGraphicsRectItem, производительность приложения нормальная, а использование процессора нормальное, от 0% до 10%. Но когда я добавляю в сцену QGraphicsItems, всегда вызывается событие рисования, что увеличивает использование процессора до 50% - 70%, а иногда приложение зависает.

Когда я устанавливаю QGraphicsView viewUpdateMode на QGraphicsView :: NoViewportUpdate, тогда использование процессора нормальное, как с QGraphicsItems, так и с QGraphicsRectItems, но когда viewUpdateMode установлен на QGraphicsView :: FullViewportUpdphics, QGraphicsView :: FullViewportUpdphics, QGraphicsView :: MinimatealView, тогда PaintGraphicsView: в QGraphicsItem вызывается в цикле, даже если в сцене нет изменений.

Таким образом я создаю QGraphicsScene, а QGrpahicsView выглядит так.

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?


person Agm    schedule 26.11.2015    source источник
comment
Добро пожаловать в SO ... Какой у вас вопрос? Для тех, кто просто бегло просматривает текст, может не понять, о чем вы спрашиваете.   -  person lhcgeneva    schedule 26.11.2015
comment
Ой, извините, забыл вопрос, отредактирую текст, чтобы добавить   -  person Agm    schedule 26.11.2015
comment
Вам действительно нужно включить mouseTracking? Возможно, это проблема и может быть причиной постоянных обновлений.   -  person TheDarkKnight    schedule 26.11.2015
comment
На самом деле, в этом нет необходимости, это был просто тест, который я проводил, чтобы проверить поведение, но с ним или без него производительность в этом случае такая же.   -  person Agm    schedule 26.11.2015
comment
Похоже, вы пытаетесь реализовать аналогичные функции с QGraphicsItemGroup. Есть ли причина, по которой вы не используете здесь QGraphicsItemGroup?   -  person TheDarkKnight    schedule 26.11.2015
comment
Сколько элементов вы добавляете в сцену, чтобы процессор сходил с ума? @Agm   -  person Alexander Tyapkov    schedule 27.11.2015
comment
Всего в сцене 22 элемента, но я не думаю, что это основная проблема, потому что сцена не должна перерисовываться все время, пока в ней нет изменений, как это происходит, когда сцена содержит только QGraphicsRectItems, где сцена перерисовывается только тогда, когда любой QGraphicsRectItem зависает или щелкает мышью.   -  person Agm    schedule 29.11.2015
comment
Я попробую использовать QGraphicsItemGroup и посмотрю, что произойдет. Я вам скажу, спасибо.   -  person Agm    schedule 29.11.2015
comment
Я обнаружил причину, по которой событие рисования вызывается все время, и это подкласс QGraphicsPixmapItem с переопределенным событием рисования. Как я могу избежать этого при переопределении события рисования QGraphicsPixmapItem?   -  person Agm    schedule 30.11.2015
comment
Это решено. Я только что удалил метод переопределения краски.   -  person Agm    schedule 01.12.2015


Ответы (1)


Вы можете использовать кеширование:

// Put this in the constructor of your QGraphicsItem
setCacheMode( QGraphicsItem::DeviceCoordinateCache );
// or
setCacheMode( QGraphicsItem::ItemCoordinateCache);
person paceholder    schedule 25.04.2016
comment
Я просто решил это. У меня был подкласс QGraphicsPixmapItem с переопределением события рисования. Я только что удалил этот метод переопределения. - person Agm; 30.04.2016