如何在QGraphicsScene上创建可调整大小的cusom小部件

时间:2014-10-10 09:25:46

标签: qt

我研究QGraphics框架并希望创建自定义可调整大小的小部件。

例如,我使用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看起来不错,但我无法找到如何添加调整大小的能力。 我搜索了Qt例子和谷歌,但找不到任何例子。

2 个答案:

答案 0 :(得分:2)

QGraphicsProxyWidget派生的GraphicsItem的大小由其边界矩形定义。我希望窗口小部件的大小可以定义其代理窗口小部件的初始大小,因此您可以先尝试更改实际的窗口小部件。

为了更改QGraphicsItem的大小,您需要从QGraphicsProxyWidget派生并覆盖其boundingRect()函数。

然后你就可以创建一个调整大小的函数来改变返回的矩形,但确保你先调用prepareGeometryChange

如果您继承QGraphicsProxyWidget并以这种方式更改其大小,则可能会调整大小,也可能不调整大小,具体取决于其实现。

我建议您首先尝试调整封闭小部件的大小。

另请注意,QGraphicsItems存在setScale函数,如果从QGraphicsProxyWidget派生,也可以在此处选择,也可以在paint函数中缩放QPainter。

答案 1 :(得分:0)

您的QGraphicsView实例可以调整大小,因此您的场景内容也会对调整大小做出反应。 这是它的工作示例(您应该在MainWindows表单上添加QGraphicsView元素):

#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;
}

但是,这不会影响场景中小部件的大小调整。要实现这一目标,请参阅Merlin's answer

此处也是使用从here获得scaling的工作解决方案的示例:

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);
}