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. Dynamically update QGraphicsItem's shape
Forum Updated to NodeBB v4.3 + New Features

Dynamically update QGraphicsItem's shape

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 1.6k 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.
  • Y Offline
    Y Offline
    yonnak
    wrote on last edited by
    #1

    Hello,

    What I'm trying to achieve is having a custom qgraphicsitem wich shape's is a filled rectangle but whith other colliding qgraphicsitem's shape substracted.

    I've tried several things but calling collidingItems() inside the shape() function of my custom qgraphicsitem seems to loop infinitely.

    Does anyone already done something like this?

    Thank you

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      What exactly are you trying to achieve? Are you looking for a visual effect only, or something else? And how long is the change in shape supposed to stay in effect?

      1 Reply Last reply
      0
      • Y Offline
        Y Offline
        yonnak
        wrote on last edited by
        #3

        Hello, thanks for repliying.

        I'm trying to develop a CAD software for print circuit board design. This feature will allow having a ground plane.
        That implies that the shape of my "recangle" should be definitive and that the resulted shape is the real shape of the item (the one used to select it)

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Asperamanca
          wrote on last edited by
          #4

          Well, collidingItem uses the shape() method, so an infinite loop is a logical consequence. However, it isn't a good idea to do all the complex calculations everytime someone calls your implementation of the shape() method: Methods like boundingRect() and shape() are very important to your performance, so they should be fast.

          The easiest way to do this is by caching. I use the following pattern for caching a shape

          • 2 class members
          mutable QPainterPath m_CachedShape;
          mutable bool m_bCachedShapeValid; // Initialize to 'false' in constructor
          
          • 2 Member functions
          void updateCachedShape() const;
          void invalidateCachedShape();
          
          • invalidateCachedShape() does nothing else but reset m_bCachedShapeValid to 'false' (but is a good place for future breakpoints)
          • updateCachedShape() updates m_CachedShape - but first checks whether any changes are necessary:
          void MyClass::updateCachedShape
          {
             if (m_bCachedShapeValid) 
             {
                return;
             }
          
             // CODE: Update m_CachedShape
          
             m_bCachedShapeValid = true;
          }
          

          Checking whether an update is even necessary breaks your infinite loop

          Finally:

          void MyClass::shape() const
          {
             updateCachedShape();
             return m_CachedShape;
          }
          1 Reply Last reply
          2
          • Y Offline
            Y Offline
            yonnak
            wrote on last edited by
            #5

            OK, I will try this, thank you!

            A 1 Reply Last reply
            0
            • Y yonnak

              OK, I will try this, thank you!

              A Offline
              A Offline
              Asperamanca
              wrote on last edited by
              #6

              @yonnak
              One tricky thing may be to decide where to call invalidateCachedShape(). Be careful about that. Too often, and you lose all the advantages. Too rare, and you use an outdated shape.
              If all else fails, you may consider invalidating the shape asynchronously (e.g. via QMetaObject::invokeMethod with option Qt::QueuedConnection), but that should not be necessary normally.
              Also, if your shape also influences how your item paints, or how your boundingRect looks, you need to call update() (for paint) and prepareGeometryChange (for boundingRect) within the invalidate method.

              1 Reply Last reply
              0
              • Y Offline
                Y Offline
                yonnak
                wrote on last edited by yonnak
                #7

                I got it working by having the path in cache recalculated on the mouseHoverEvent of the item, but it was too much to compute for each event and the refresh was too slow.
                I ended up deactivated the complex shape of the item when moving or adding "classics" items and recalculate the shape only when editing is done.

                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