Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGraphicsScene/QGraphicsView performance
Forum Updated to NodeBB v4.3 + New Features

QGraphicsScene/QGraphicsView performance

Scheduled Pinned Locked Moved General and Desktop
15 Posts 6 Posters 6.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    onurozcelik
    wrote on last edited by
    #1

    Hi

    I am using QGraphicsScene/QGraphicsView pair in my project
    I have performance issue with this pair.
    I added my custom graphics items to scene and displayed the contents with view. After that my custom graphics items paint method continuously called by scene(just like infinite loop). This makes 25% of CPU usage(approximately 400 items on scene). What may cause this behaviour?

    Here is one my item implementation:

    @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 read x and y coordinates from xml file. For this item x and y coordinates are 239,344 respectively

    1 Reply Last reply
    0
    • M Offline
      M Offline
      MarekR22
      wrote on last edited by
      #2

      First ask proper question (some solid data not just "I have a problem").
      Secondly your "custom graphics items" must be faulty.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jorj
        wrote on last edited by
        #3

        can you post some code for the items?

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jorj
          wrote on last edited by
          #4

          you are emitting signals during your paint method, if these are connected to the (im assuming) game logic, and trigger a redraw, you will get an infinite ish loop, possibly you should restructure you game logic to be separate form the paint methods.

          that is my first thought anyway...

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zgulser
            wrote on last edited by
            #5

            Hi,

            First of all, your paint methods will always be called when the view interacts with mouse unless you ignore the mouse events.

            Secondly, paint ,as it stands, should only perform painting but as far as I see you do many things beyond painting. Maybe that's why your items are slow. Plus remember that they will much faster in release mode(in case if you are working in debug mode).

            Finally, what's the renderer?

            1 Reply Last reply
            0
            • O Offline
              O Offline
              onurozcelik
              wrote on last edited by
              #6

              [quote author="zgulser" date="1297760455"]Finally, what's the renderer?
              [/quote]

              QSvgRenderer instance pointer.

              1 Reply Last reply
              0
              • O Offline
                O Offline
                onurozcelik
                wrote on last edited by
                #7

                [quote author="Jorj" date="1297696052"]you are emitting signals during your paint method, if these are connected to the (im assuming) game logic, and trigger a redraw, you will get an infinite ish loop[/quote]

                I commented emit stuff but CPU usage did not change.

                1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  zgulser
                  wrote on last edited by
                  #8

                  Ok.

                  I think you should do all other controlling stuff outside the paint method( I bet you know signal-slot issue) and just perform renderer->render(painter,boundingRect()); in it.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    MarekR22
                    wrote on last edited by
                    #9

                    As I can see now you mess up everything with everything.

                    • paint method should do only painting nothing else (performance reasons)
                    • sizeHint is hardcoded I doubt you reale need this
                    • boundingRect is wrong for sure.
                    • you messing around with properties when it is not needed (this is needed if code supposed to manipulate objects with unknown api/structure).

                    Maybe explain what this should show!

                    [EDIT: fixed list - use "*" instead of "-" as "bullets", Volker]

                    1 Reply Last reply
                    0
                    • O Offline
                      O Offline
                      onurozcelik
                      wrote on last edited by
                      #10

                      MarekR22

                      How should I implement boundingRect()?
                      Sample code please.

                      1 Reply Last reply
                      0
                      • Z Offline
                        Z Offline
                        zgulser
                        wrote on last edited by
                        #11

                        Although it won't solve your problem totally, it should be something like;

                        @

                        void Item::setBoundingRect(const QRect& pBoundingRect)
                        {
                        mBoundingRect = pBoundingRect;
                        }

                        const QRect& Item::getBoundingRect()
                        {
                        return mBoundingRect;
                        }

                        const QRect& Item::boundingRect()
                        {
                        return getBoundingRect();
                        }
                        @

                        1 Reply Last reply
                        0
                        • I Offline
                          I Offline
                          ivan
                          wrote on last edited by
                          #12

                          You could also cache the svg render output to a pixmap.

                          Ivan Čukić | ivan.cukic(at)kde.org | KDE e.V.
                          Qt Ambassador (from the old Nokia days)

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            MarekR22
                            wrote on last edited by
                            #13

                            [quote author="onurozcelik" date="1297780179"]MarekR22

                            How should I implement boundingRect()?
                            Sample code please.[/quote]
                            The joke is that you don't have to. QGraphicsWidget returns boundingRect which in most cases should be ok.
                            But like I said describe what you are trying to achieve then we will show you how code should look like.
                            Note there is a class "QGraphicsSvgItem":http://doc.trolltech.com/latest/qgraphicssvgitem.html. Maybe this is enough for you.

                            1 Reply Last reply
                            0
                            • O Offline
                              O Offline
                              onurozcelik
                              wrote on last edited by
                              #14

                              implementing boundingRect correctly solved the infinite repaint loop problem.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                [quote author="zgulser" date="1297781851"]
                                Although it won't solve your problem totally, it should be something like;

                                @

                                void Item::setBoundingRect(const QRect& pBoundingRect)
                                {
                                mBoundingRect = pBoundingRect;
                                }

                                const QRect& Item::getBoundingRect()
                                {
                                return mBoundingRect;
                                }

                                const QRect& Item::boundingRect()
                                {
                                return getBoundingRect();
                                }
                                @[/quote]

                                For performance critical code, you should just inline the stuff above.

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved