QGraphicsItem Moving and crop



  • Hello,

    I'm working with some QGraphicsSvgItems

    Currently I have set every item in place.

    Last feature is to move some of them when some event triggers.

    I can now move the Items I want with:
    svgItem->moveBy(0, 50);

    Now the item looks funny after it goes down by 50 and overlaps the item underneath.
    I would like to crop the bottom of the item by 50.

    I tried:
    svgItem->boundingRect().setBottom(-50);
    It doesn't seem to have any effect.
    Also tried several other functions which doesn't seem to do anything either.

    While browsing the documentation of scenes, transformations and boundingrects etc. I'm getting a bit confused.

    What is the best way to crop away part of the Item?

    thanks.



  • @lietak said in QGraphicsItem Moving and crop:

    svgItem->boundingRect().setBottom(-50);

    svgItem->boundingRect().setBottom(-50);
    

    That really doesn't have any effect: You get a copy of the boundingRect, then change that copy. The result is not used, and therefore discarded. If you use the standard QGraphicsSvgItem, you don't control it's boundingRect - the item itself decides how big it is.
    One way around:

    • Create your own QGraphicsItem-derived class where you can fully control the boundingRect - let's call it ClipperItem
    • Set the flag QGraphicsItem::ItemClipsChildrenToShape
    • Make the QGraphicsSvgItem a child of a ClipperItem

    Adjust the ClipperItem's boundingRect as needed to show only the part of your Svg you want to show

    Edit:
    For a quick tryout, you can use QGraphicsWidget and use setGeometry to define it's size and position. However, for better performance (and if you don't need all the other features of QGraphicsWidget), I would implement a QGraphicsItem-derived class as final solution.


  • Moderators

    @lietak
    For real clipping you can subclass QGraphicsSvgItem:

    class MyGraphicsSvgItem : public QGraphicsSvgItem
    {
    public:
         MyGraphicsSvgItem(QGraphicsItem* parent = Q_NULLPTR) : QGraphicsSvgItem(parent)
         {
          this->setFlag( QGraphicsItem::ItemClipsToShape );
        }
    
        virtual QPainterPath shape() const Q_DECL_OVERRIDE {
            QPainterPath s = QGraphicsSvgItem::shape();
            QRectF clipRect = this->boundingRect();
                  clipRect.setTop( clipRect.bottom()-50 );
            QPainterPath clipPath;
                  clipPath.addRect(  clipRect );
             s = s.subtracted( clipPath );
            return s;
       }
    };
    

    (untested)



  • Ok thanks for the replies and help.

    I kinda knew I would probably had to subclass it. Was mostly wondering if there was some other way.

    So I'll try it out.

    Edit.
    I used @raven-worx solution
    It works. Awesome.
    Just made -50 as variable so I can change it per item :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.