如何根据 QGraphicScene 缩放/调整 QGraphicsWidget 的大小?
Posted
技术标签:
【中文标题】如何根据 QGraphicScene 缩放/调整 QGraphicsWidget 的大小?【英文标题】:How do I scale/resize a QGraphicsWidget based on the QGraphicScene? 【发布时间】:2018-08-28 15:39:51 【问题描述】:我希望我的 QGraphicsWidget 根据场景的大小来缩放它的大小。我目前拥有的 QGraphicsWidget 是一个固定大小,具体取决于 sizeHint 的返回值(QGraphicsWidget 始终为 200 x 200)。下面附上最小的例子:
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include "RectangleWidget.h"
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene * m_scene;
QGraphicsView * m_view;
RectangleWidget * m_rectangleWidget;
;
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui->setupUi(this);
m_scene = new QGraphicsScene(this);
m_view = new QGraphicsView(m_scene, this);
m_view->setAlignment(Qt::AlignLeft | Qt::AlignTop);
m_rectangleWidget = new RectangleWidget();
m_scene->addItem(m_rectangleWidget);
setCentralWidget(m_view);
MainWindow::~MainWindow()
delete ui;
矩形小部件.h:
#ifndef RECTANGLEWIDGET_H
#define RECTANGLEWIDGET_H
#include <QGraphicsLinearLayout>
#include <QGraphicsWidget>
class RectangleWidget: public QGraphicsWidget
public:
RectangleWidget(QGraphicsWidget* parent = nullptr);
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
void setGeometry(const QRectF &geom) override;
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;
;
#endif // RECTANGLEWIDGET_H
矩形小部件.cpp:
#include "rectanglewidget.h"
#include <QPainter>
RectangleWidget::RectangleWidget(QGraphicsWidget* parent)
void RectangleWidget::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget /*= 0*/)
Q_UNUSED(widget);
Q_UNUSED(option);
//Draw border
painter->drawRoundedRect(boundingRect(), 0.0, 0.0);
QRectF RectangleWidget::boundingRect() const
return QRectF(QPointF(0,0), geometry().size());
void RectangleWidget::setGeometry(const QRectF &geom)
prepareGeometryChange();
QGraphicsLayoutItem::setGeometry(geom);
setPos(geom.topLeft());
QSizeF RectangleWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
switch (which)
case Qt::MinimumSize:
return QSizeF(200, 200);
default:
break;
return constraint;
对此的任何帮助将不胜感激。
【问题讨论】:
小部件的大小究竟应该如何取决于场景的大小?他们应该平等吗? 任何比例都可以。让我们继续使用 1/2 的场景大小。 【参考方案1】:背景
您的 QGraphicsWidget 必须注意两件事:
-
添加到场景时
为此,您必须重新实现 QGraphicsWidget::itemChange
并查找 QGraphicsItem::ItemSceneHasChanged
类型的更改。
-
当此场景的大小发生变化时
这可以通过将插槽或 lambda 函数连接到 QGraphicsScene::sceneRectChanged
信号来完成。
解决方案
根据给定的解释,我的解决方案如下:
在RectangleWidget.h中QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override;
之后添加:
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
private:
QSize m_rectSize;
在 RectangleWidget.cpp 中将 return QSizeF(200, 200);
更改为 return m_rectSize;
并在末尾添加:
QVariant RectangleWidget::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
if (change == ItemSceneHasChanged)
connect(value.value<QGraphicsScene *>(), &QGraphicsScene::sceneRectChanged, [this](const QRectF &rect)
m_rectSize.setWidth(rect.size().width());
m_rectSize.setHeight(rect.size().height());
);
return QGraphicsWidget::itemChange(change, value);
最后,在MainWindow.cpp中m_scene->addItem(m_rectangleWidget);
之后设置sceneRect
如下:
m_scene->setSceneRect(0, 0, 100, 400);
注意:矩形会响应场景的变化,而不是视图。所以如果你调整窗口大小,矩形不会被调整大小。
调整
这将使矩形与场景的大小完全相同。如果你想要不同的比率,说0.5
,而不是m_rectSize.setWidth(rect.size().width());
,分别写m_rectSize.setWidth(rect.size().width() / 2);
,m_rectSize.setHeight(rect.size().height() / 2);
。
【讨论】:
我现在得到了一个 50x200 的固定矩形,现在有你的更改。我们是不是错过了什么。可以发完整的 4 个文件吗? 有没有办法将窗口大小与场景大小联系起来? @MichaelJapzon,有。然而,这已经是另一个问题,需要另一种解决方案。充其量将这个标记为已解决并询问另一个关于 QGraphicsView 的信息。以上是关于如何根据 QGraphicScene 缩放/调整 QGraphicsWidget 的大小?的主要内容,如果未能解决你的问题,请参考以下文章
如何在android中根据谷歌地图不同的缩放级别调整谷歌地图标记的大小