kaa
kaa

Reputation: 1367

How to create resizable cusom widget on the QGraphicsScene

I study QGraphics framework and want to create custom resizable widget.

For example I created a proxy widget with QTextEdit

QGraphicsLinearLayout* l = new QGraphicsLinearLayout;
QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget;
proxy->setWidget(  new QTextEdit );
proxy->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
l->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
l->addItem( proxy );

QGraphicsWidget* w = new QGraphicsWidget;
w->setLayout( l );
w->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
w->setFlag( QGraphicsItem::ItemIsMovable );

scene->addItem( w ); 

Widget looks fine, but I can't find out how add ability to resize it. I searched in the Qt Examples, and google, but can't find any example.

Upvotes: 5

Views: 2798

Answers (2)

Max Go
Max Go

Reputation: 2102

You should have your QGraphicsView instance resizable, so your scene content will react on resizing too. Here it's working example (you should add QGraphicsView element on your MainWindows form):

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTextEdit>
#include <QPushButton>
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QGraphicsScene>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QGraphicsScene* scene = new QGraphicsScene(this);
    QGraphicsWidget *textEdit = scene->addWidget(new QTextEdit);
    QGraphicsWidget *pushButton = scene->addWidget(new QPushButton);

    QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
    layout->addItem(textEdit);
    layout->addItem(pushButton);

    QGraphicsWidget *form = new QGraphicsWidget;
    form->setLayout(layout);
    scene->addItem(form);

    ui->graphicsView->setScene(scene);
    setCentralWidget(ui->graphicsView);
}

MainWindow::~MainWindow()
{
    delete ui;
}

However this doesn't affect sizing of the widgets inside scene. To achieve that see Merlin's answer.

Also here it's example of working solution with using of scaling obtained from here:

void MyGraphicsView::resizeEvent(QResizeEvent* event)
{
     QGraphicsView::resizeEvent(event);

     QSize viewportSize = this->viewport().size();
     QSize imageGridSize = ...; //size of all images (bounding rect)

     qreal factor = viewportSize.width() / imageGridSize.width();
     if( viewportSize.height() < (imageGridSize * factor).height() )
        factor *= viewSize.height() / (imageSize * factor).height();

     this->resetTransform();
     QTransform transform = this->transform();
           transform.scale(factor, factor);
     this->setTransform(transform);
}

Upvotes: 0

TheDarkKnight
TheDarkKnight

Reputation: 27611

A GraphicsItem's size, of which QGraphicsProxyWidget derives, is defined by its bounding rectangle. I expect the size of the widget would define the initial size of its proxy widget, so you could try changing the actual widget first.

In order to change the QGraphicsItem's size, you'd need to derive from QGraphicsProxyWidget and override its boundingRect() function.

Then you'd be able to create a resize function to change the returned rectangle, but ensure you call prepareGeometryChange first.

If you do inherit from QGraphicsProxyWidget and change its size this way, the enclosed widget may or may not be resized, depending upon its implementation.

I suggest you start by trying to resize the enclosing widget first.

Also note that there exists a setScale function for QGraphicsItems, which may also be an option here, as well as being able to scale the QPainter, in the paint function, if you derive from QGraphicsProxyWidget.

Upvotes: 2

Related Questions