Search code examples
c++qtqgraphicsviewqgraphicssceneqgraphicsrectitem

Why I can't enlarge a widget added to QGraphicScene by QSizeGrip?


I have added a widget to a graphic scene QGraphicScene through a QGraphicsProxyWidget. To move it I have set QGraphicsRectitem as its parent. The widget is resized with the use of a sizegrip.

The first time I create an object I can enlarge it upto some dimension. The second time I can enlarge it less than the first one. The third time less than the second one and so on.

It seems to me that it behaves randomly. Why is this happening?

Here is the code:

void GraphicsView::dropEvent(QDropEvent *event)// subclass of QGraphicsView
{

  if(event->mimeData()->text() == "Dial")
  {
   auto *dial= new Dial;      // The widget
   auto *handle = new QGraphicsRectItem(QRect(event->pos().x(),event->pos().y(), 120, 120));    // Created to move and select on scene
   auto *proxy = new QGraphicsProxyWidget(handle); // Adding the widget through the proxy
   dial->setGeometry(event->pos().x()+10,event->pos().y()+10, 100, 100);
   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 

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

code

I cannot enlarge the widget more than that, what is shown in the image.


Solution

  • Your Dial can't be resized past the GraphicView's right (horizonally) and bottom (vertically) edges. If you make the scene big enough, say 2000x2000 (setSceneRect(2000, 2000);), scrollbars will appear. If you move the scrollbars manually, you will be able to enlarge your widgets more.

    You could also experiment with automatic scrollbar movement by changing the lambda function like this:

    connect(dial, &Dial::sizeChanged, [this, dial, handle](){
        handle->setRect(dial->geometry().adjusted(-10, -10, 10, 10));
    
        int dx = handle->rect().bottomRight().x() > viewport()->rect().bottomRight().x();
        int dy = handle->rect().bottomRight().y() > viewport()->rect().bottomRight().y();
    
        if (dx > 0) {
            horizontalScrollBar()->setValue(horizontalScrollBar()->value() + dx);
        }
    
        if (dy > 0) {
            verticalScrollBar()->setValue(verticalScrollBar()->value() + dy);
        }
    });
    

    Please note, that although this code works, is is very cumbersome. However, it could give you an idea how to start.