QGraphicsScene / QGraphicsView Performance

I am using a pair of QGraphicsScene / QGraphicsView in my project I have a performance problem with this pair. I added my own graphic elements to the scene and displayed the content with the view. After that, my method of drawing graphic elements is constantly called by the scene (like an endless loop). This makes% 25 use of the processor (approximately 400 elements per scene). What can cause this behavior?

Here is one implementation of mine:

class LevelCrossingItem : public QGraphicsWidget { public: LevelCrossingItem(QString _id,qreal _x,qreal _y); ~LevelCrossingItem(); QRectF boundingRect() const; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */); void readStateBits(); bool isClosed(); bool isGateArmBroken(); bool isOpenedDuringRouteTanzimCompleted(); bool hasDataConsistencyWarning(); int type() const {return Type;} private slots: void setVisible(bool); private: enum {Type = FIELDLEVELCROSSING}; QString m_id; QString m_source; short m_closedState; short m_brokenGateArmState; short m_openedDuringRouteTanzimCompletedState; short m_dataConsistencyWarningState; QBitArray stateBitArray; qreal x,y; QSvgRenderer *renderer; }; #include "levelcrossing.h" LevelCrossingItem::LevelCrossingItem(QString _id,qreal _x,qreal _y):m_id(_id),x(_x),y(_y),stateBitArray(4) { m_source = LEVELCROSSING_RESOURCE_PATH.arg("open"); renderer = new QSvgRenderer; setStateArray(stateBitArray); setZValue(-0.5); } LevelCrossingItem::~LevelCrossingItem() { delete renderer; } void LevelCrossingItem::setVisible(bool visible) { QGraphicsItem::setVisible(visible); } QRectF LevelCrossingItem::boundingRect() const { return QRectF(QPointF(x,y),sizeHint(Qt::PreferredSize)); } QSizeF LevelCrossingItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { return QSizeF(50,270); } void LevelCrossingItem::readStateBits() { m_closedState = property("Closed").toInt(); m_brokenGateArmState = property("Broken").toInt(); m_openedDuringRouteTanzimCompletedState = property("OpenedOnRouteWarning").toInt(); m_dataConsistencyWarningState = property("DataConsistencyWarning").toInt(); stateBitArray.setBit(0,qvariant_cast<bool>(m_closedState)); stateBitArray.setBit(1,qvariant_cast<bool>(m_brokenGateArmState)); stateBitArray.setBit(2,qvariant_cast<bool>(m_openedDuringRouteTanzimCompletedState)); stateBitArray.setBit(3,qvariant_cast<bool>(m_dataConsistencyWarningState)); setStateArray(stateBitArray); } void LevelCrossingItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) { Q_UNUSED(option); Q_UNUSED(widget); readStateBits(); m_closedState == Positive ? m_source = LEVELCROSSING_RESOURCE_PATH.arg("closed") : m_source = LEVELCROSSING_RESOURCE_PATH.arg("open"); m_brokenGateArmState == Positive ? m_source = LEVELCROSSING_RESOURCE_PATH.arg("broken") : m_source = m_source; if(m_openedDuringRouteTanzimCompletedState == Positive) { setWarningVisible(OOR_WRN.arg(name()).arg(interlockingRegionId()),true); if(stateChanged()) emit itemAlarmOccured(m_id,LevelCrossingIsOpenDuringTanzimCompleted); } else setWarningVisible(OOR_WRN.arg(name()).arg(interlockingRegionId()),false); if(m_dataConsistencyWarningState == Positive) { setWarningVisible(DC_WRN.arg(name()).arg(interlockingRegionId()),true); if(stateChanged()) emit itemAlarmOccured(m_id,LevelCrossingDataConsistency); } else setWarningVisible(DC_WRN.arg(name()).arg(interlockingRegionId()),false); renderer->load(m_source); renderer->render(painter,boundingRect()); } bool LevelCrossingItem::isClosed() { return m_closedState == Positive; } bool LevelCrossingItem::isGateArmBroken() { return m_brokenGateArmState == Positive; } bool LevelCrossingItem::isOpenedDuringRouteTanzimCompleted() { return m_openedDuringRouteTanzimCompletedState == Positive; } bool LevelCrossingItem::hasDataConsistencyWarning() { return m_dataConsistencyWarningState == Positive; } 

I am reading x and y coordinates from xml file. For this element, the x and y coordinates are 239.344, respectively

+4
source share
1 answer

Most likely, your graphic object has errors in implementation. I had similar behavior, but I could not understand what exactly caused it. I suspect this happens when you go beyond the bounding box. This causes some cleaning procedure, which, in turn, causes the item to be redrawn, and here the loop goes. In the end, I solved the problem by carefully checking the implementation of my custom graphic element and making sure that:

  • This is not a picture outside of MyGraphicsItem::boundingRect . Use painter->setClipRect(boundingRect())
  • MyGraphicsItem::shape does not intersect with MyGraphicsItem::boundingRect .
  • If you override any other QGraphicsItem functions, make sure your implementation is correct.

Hope this helps. Feel free to publish the source code of your graphic element, it will be easier to find the problem.

+4
source

Source: https://habr.com/ru/post/1339611/


All Articles