我是Qt新手。我阅读了教程,但仍然不了解SceneRect的工作原理。
运行此代码时,图像(绿色)显示在中间(可能是默认位置,对吧?)
MyApplication.cpp
ui.setupUi(this);
ui.graphicsView->setBackgroundBrush(Qt::red);
_graphicsScene = make_unique<QGraphicsScene>(this);
ui.graphicsView->setScene(_graphicsScene.get());
_graphicsScene->setBackgroundBrush(Qt::blue);
QImage img("C:\\Users\\user\\Downloads\\img.png");
auto pixImg = QPixmap::fromImage(img);
pixImg = pixImg.scaled(QSize(50, 50), Qt::KeepAspectRatio);
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixImg);
_graphicsScene->addPixmap(pixImg);
ui_MyApplication.h
void setupUi(QMainWindow *MyApplicationToolClass)
{
if (MyApplicationToolClass->objectName().isEmpty())
MyApplicationToolClass->setObjectName(QString::fromUtf8("MyApplicationToolClass"));
MyApplicationToolClass->resize(465, 372);
centralWidget = new QWidget(MyApplicationToolClass);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
entitiesView = new QGraphicsView(centralWidget);
entitiesView->setObjectName(QString::fromUtf8("entitiesView"));
entitiesView->setGeometry(QRect(30, 20, 401, 281));
MyApplicationToolClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MyApplicationToolClass);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 465, 21));
MyApplicationToolClass->setMenuBar(menuBar);
mainToolBar = new QToolBar(MyApplicationToolClass);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MyApplicationToolClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MyApplicationToolClass);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MyApplicationToolClass->setStatusBar(statusBar);
retranslateUi(MyApplicationToolClass);
QMetaObject::connectSlotsByName(MyApplicationToolClass);
} // setupUi
我想,如果我将sceneRect
的{{1}}设置为(0,0,100,100)
,则图像会显示在左上角,但会稍微向上移动。
我将_entitiesScene->setSceneRect(0, 0, 100, 100);
设置为sceneRect
,只是向左上移
答案 0 :(得分:0)
对场景的景象,项目的boundingRect的简短回顾:
此纯虚函数将项目的外部边界定义为矩形;所有绘画都必须限制在项目的边界区域内。 QGraphicsView使用它来确定该项目是否需要重绘。
尽管项目的形状可以是任意的,但边界矩形始终为矩形,并且不受项目变换的影响。
此属性保存场景矩形;场景的边界矩形
场景矩形定义场景的范围。 QGraphicsView主要使用它来确定视图的默认可滚动区域,QGraphicsScene主要使用它来管理项目索引。
如果未设置,或者将其设置为null QRectF,则SceneRect()将返回自创建场景以来场景中所有项目的最大边界矩形(即,当添加或移动项目时矩形会增大)。场景,但永远不会缩小)。
可以直接设置场景矩形。这将影响视图中的渲染。如果声称场景与所有项目的边界矩形都不相同,则视图将分别考虑这一点。
OP的缺失部分是恕我直言,渲染中还有其他需要考虑的地方:
当整个场景可见时,此属性将场景在视图中对齐。
如果整个场景在视图中可见(即,没有可见的滚动条),则视图的对齐方式将决定场景在视图中的渲染位置。例如,如果对齐方式是Qt :: AlignCenter(默认设置),则场景将在视图中居中;如果对齐方式是(Qt :: AlignLeft | Qt :: AlignTop),则场景将在顶部渲染。 -视图的左上角。)
为此,QGraphicsView
考虑其自身的视图大小和场景rect,并计算相应的平移以实现所需的对齐。转换用于更新QGraphicsView::transform
,后者将场景坐标映射到视口坐标。
一个小例子来说明这一点(testQGraphicsSceneSceneRect.cc
):
#include <QtWidgets>
// returns a random floating point number in [min, max).
qreal randF(qreal min, qreal max)
{
return qrand() / (RAND_MAX + 1.0) * (max - min) + min;
}
// returns a random color.
QColor randColor()
{
return QColor(
(int)256 * randF(0.0, 1.0),
(int)256 * randF(0.0, 1.0),
(int)256 * randF(0.0, 1.0));
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWin;
qWin.setWindowTitle("QSceneGraph::sceneRect Demo");
QToolBar qToolbar;
QAction qCmdAdd("Add Rect");
qToolbar.addAction(&qCmdAdd);
QAction qCmdClear("Clear Scene");
qToolbar.addAction(&qCmdClear);
qToolbar.addSeparator();
QWidget qEditAlign;
QGridLayout qGridAlign; QButtonGroup qBtnGrp;
QRadioButton qBtnTL, qBtnTC, qBtnTR;
qGridAlign.addWidget(&qBtnTL, 0, 0);
qBtnGrp.addButton(&qBtnTL, Qt::AlignLeft | Qt::AlignTop);
qGridAlign.addWidget(&qBtnTC, 0, 1);
qBtnGrp.addButton(&qBtnTC, Qt::AlignHCenter | Qt::AlignTop);
qGridAlign.addWidget(&qBtnTR, 0, 2);
qBtnGrp.addButton(&qBtnTR, Qt::AlignRight | Qt::AlignTop);
QRadioButton qBtnCL, qBtnCC, qBtnCR;
qGridAlign.addWidget(&qBtnCL, 1, 0);
qBtnGrp.addButton(&qBtnCL, Qt::AlignLeft | Qt::AlignVCenter);
qGridAlign.addWidget(&qBtnCC, 1, 1);
qBtnGrp.addButton(&qBtnCC, Qt::AlignHCenter | Qt::AlignVCenter);
qGridAlign.addWidget(&qBtnCR, 1, 2);
qBtnGrp.addButton(&qBtnCR, Qt::AlignRight | Qt::AlignVCenter);
QRadioButton qBtnBL, qBtnBC, qBtnBR;
qGridAlign.addWidget(&qBtnBL, 2, 0);
qBtnGrp.addButton(&qBtnBL, Qt::AlignLeft | Qt::AlignBottom);
qGridAlign.addWidget(&qBtnBC, 2, 1);
qBtnGrp.addButton(&qBtnBC, Qt::AlignHCenter | Qt::AlignBottom);
qGridAlign.addWidget(&qBtnBR, 2, 2);
qBtnGrp.addButton(&qBtnBR, Qt::AlignRight | Qt::AlignBottom);
qEditAlign.setLayout(&qGridAlign);
qToolbar.addWidget(&qEditAlign);
qWin.addToolBar(&qToolbar);
QGraphicsView qGView;
QGraphicsScene qGScene;
qGView.setScene(&qGScene);
qWin.setCentralWidget(&qGView);
qWin.show();
// activate button for default align of qGView
qBtnGrp.button(qGView.alignment())->setChecked(true);
// install signal handlers
QObject::connect(&qCmdAdd, &QAction::triggered,
[&]() {
// add rect
QRectF qRect(
randF(-50.0, 50.0), randF(-50.0, 50.0),
randF(10.0, 100.0), randF(10.0, 100.0));
qGScene.addRect(qRect, QPen(randColor(), 2), randColor());
// report
qDebug() << "new rect:" << qRect;
qDebug() << "scene rect:" << qGScene.sceneRect();
qDebug() << "scene (0, 0) in view at:"
<< qGView.mapFromScene(QPointF(0.0, 0.0));
qDebug() << "top left view corner in scene at:"
<< qGView.mapToScene(QPoint(0, 0));
});
QObject::connect(&qCmdClear, &QAction::triggered,
[&]() {
// clear scene
qGScene.clear();
// reset sceneRect
qGScene.setSceneRect(QRect());
});
QObject::connect(&qBtnGrp,
(void(QButtonGroup::*)(int, bool))&QButtonGroup::buttonToggled,
[&](int id, bool checked) {
if (checked) qGView.setAlignment((Qt::Alignment)id);
});
// run time loop
return app.exec();
}
相应的Qt项目(testQGraphicsSceneSceneRect.pro
):
SOURCES = testQGraphicsSceneSceneRect.cc
QT += widgets
在cygwin64中进行了编译和测试:
$ qmake-qt5 testQGraphicsSceneSceneRect.pro
$ make && ./testQGraphicsSceneSceneRect
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQGraphicsSceneSceneRect.o testQGraphicsSceneSceneRect.cc
g++ -o testQGraphicsSceneSceneRect.exe testQGraphicsSceneSceneRect.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
new rect: QRectF(-4.13499,25.5605 21.8384x10.0007)
scene rect: QRectF(-5.13499,24.5605 23.8384x12.0007)
scene (0, 0) in view at: QPoint(120,3)
top left view corner in scene at: QPointF(-120,-3)
new rect: QRectF(-46.5428,33.0965 56.7475x44.5152)
scene rect: QRectF(-47.5428,24.5605 66.2462x54.0512)
scene (0, 0) in view at: QPoint(141,-17)
top left view corner in scene at: QPointF(-141,17)
然后,我通过单击鼠标来更改对齐方式:
scene (0, 0) in view at: QPoint(47,-24)
top left view corner in scene at: QPointF(-47,24)