I have a QWidget
which is holding a QGraphicsScene
with several items. Some of those items are QGraphicsRectItem
s and subclassed QGraphicsItem
s. When in the scene there are QGraphicsRectItem
s only, the performance of the application is fine and the processor usage is normal, between 0% - 10%. But when I add to the scene the QGraphicsItem
s, the paint event is always being called, and that makes the processor usage raises to 50% - 70% and sometimes the application gets frozen.
When I set the QGraphicsView viewUpdateMode to QGraphicsView::NoViewportUpdate, then the processor usage is fine, with both QGraphicsItems and QGraphicsRectItems, but when the viewUpdateMode is set to QGraphicsView::FullViewportUpdate, QGraphicsView::MinimalViewportUpdate or QGraphicsView::BoundingRectViewportUpdate then the paint event in QGraphicsItem is called in a loop, even if there's no modification on the scene.
This is the way I create the QGraphicsScene and the QGrpahicsView is like this.
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);
And the subclassed QGraphicsItem is like this:
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();
}
so the question is, how can I do to make the paint event being called only when there is any modification in the scene, or in any object on the scene, and not having the QGraphicsScene being calling QGraphicsItem paint event all the time?