c++qtqgraphicsviewqgraphicssceneqgraphicsrectitem

How to resize QWidget added in QGraphicScene through QGraphicsProxy?


I have added a widget to a graphic scene (QGraphicScene) through a QGraphicsProxyWidget. To move and select the widget added QGraphicsRectItem handle. To resize widget added QSizegrip to widget. But when i resize widget more than the QGraphicsRect item rect right and bottom edges goes behind .How to overcome this problem? When i resize widget graphics rect item should resize or vice-versa should happen. how to do this? Any other ideas are welcome. Here is the code

     auto *dial= new QDial();                                        // The widget
     auto *handle = new QGraphicsRectItem(QRect(0, 0, 120, 120));    // Created to move and select on scene
     auto *proxy = new QGraphicsProxyWidget(handle);                 // Adding the widget through the proxy

     dial->setGeometry(0, 0, 100, 100);
     dial->move(10, 10);

     proxy->setWidget(dial);

     QSizeGrip * sizeGrip = new QSizeGrip(dial);
     QHBoxLayout *layout = new QHBoxLayout(dial);
     layout->setContentsMargins(0, 0, 0, 0);
     layout->addWidget(sizeGrip, 0, Qt::AlignRight | Qt::AlignBottom);

     handle->setPen(QPen(Qt::transparent));
     handle->setBrush(Qt::gray);
     handle->setFlags(QGraphicsItem::ItemIsMovable | 
     QGraphicsItem::ItemIsSelectable);

     Scene->addItem(handle); // adding to scene 

Here is the Output::
Before Resize
Before Resize After Resize After Resize


Solution

  • Cause

    The QGraphicsRectItem, which you use as a handle, is not aware of the size changes of QDial, so it does not respond by resizing itself.

    Limitation

    QWidget and its subclases do not provide something like a sizeChanged signal out of the box.

    Solution

    Considering the cause and the given limitation, my solution would be the following:

    1. In a subcalss of QDial, say Dial, add a new signal void sizeChanged();
    2. Reimplement the resizeEvent of Dial like this:

    in dial.cpp

    void Dial::resizeEvent(QResizeEvent *event)
    {
        QDial::resizeEvent(event);
    
        sizeChanged();
    }
    
    1. Change auto *dial= new QDial(); to auto *dial= new Dial();
    2. Add the following code after Scene->addItem(handle); // adding to scene:

    in the place, where your example code is

    connect(dial, &Dial::sizeChanged, [dial, handle](){
            handle->setRect(dial->geometry().adjusted(-10, -10, 10, 10));
        });
    

    Note: This could be also solved using eventFilter instead of subclassing QDial. However, from your other question I know that you already subclass QDial, that is why I find the proposed solution more suitable for you.

    Result

    This is the result of the proposed solution:

    before resize

    after resize