QGraphicsScene does not fit QGraphicsView full size
-
The red square is drawn using "m_view->setStyleSheet("border: 5px solid red");" so technically this is the border of the QGraphicsView object and indeed this object is defined as the central widget. So it is still not clear to me why the QGraphicsScene does not fit the QGraphicsView.
Since I have no toolbars, no dock, etc. (I have only one widget in my mainwindow, defined as the central widget). So everything should scale the full size of the mainwindow, but it is not.How would you rewrite my code to get what I look for?
-
Actually this code is a sample of my whole code where the QGraphicsView is inside a widget, so I experience the same issue either with QMainWindow or with QWidget.
@JonB said in QGraphicsScene does not fit QGraphicsView full size:
- Maybe your scene is already the full size of the view (or vice versa). Maybe you actually need to enlarge the scene/view to fill the whole window.
Why not but I am not sure to know how to do it.
-
@odelaune said in QGraphicsScene does not fit QGraphicsView full size:
m_view = new QGraphicsView();
m_view = new QGraphicsView( this );
QGraphicsScene *scene = new QGraphicsScene( m_view or this );
m_view->setRenderHint(QPainter::Antialiasing, true);
m_view->setScene(scene); ///The view does not take ownership of scene with this call.Try to change resize policy of scene
check this example: https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/graphicsview/elasticnodes?h=6.3
-
Hmmm, here is my code now
main.cpp
// Qt headers #include <QApplication> #include "test.h" int main(int argc, char *argv[]) { QApplication application(argc, argv); Test *applicationWindow = new Test(); applicationWindow->setMinimumWidth(400); applicationWindow->setMinimumHeight(400); applicationWindow->show(); return application.exec(); }
test.cpp
// Qt headers #include <QPixmap> #include <QGraphicsPixmapItem> #include <QGraphicsRectItem> #include <QPainter> #include <QPen> #include <QResizeEvent> // Other headers #include "test.h" Test::Test(QWidget* parent /*=nullptr*/): QMainWindow(parent) { m_view = new QGraphicsView(this); // draw border of the QGraphicsView m_view->setStyleSheet("border: 5px solid red"); m_scene = new QGraphicsScene(m_view); m_view->setRenderHint(QPainter::Antialiasing, true); m_view->setScene(m_scene); m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QPixmap img("tmp.svg"); QGraphicsPixmapItem *item = m_scene->addPixmap(img); // draw border of the QGraphicsScene QGraphicsRectItem *rect_item = m_scene->addRect(m_scene->sceneRect()); rect_item->setParentItem(item); QPen pen = QPen(Qt::black); pen.setWidth(10); rect_item->setPen(pen); // set the mapView as the central widget setCentralWidget(m_view); m_view->show(); m_view->fitInView (m_scene->itemsBoundingRect(),Qt::IgnoreAspectRatio); // useless here } // destructor Test::~Test() { } void Test::resizeEvent(QResizeEvent* event) { if(!m_scene) return; QRectF bounds = m_scene->itemsBoundingRect(); m_view->fitInView(bounds, Qt::IgnoreAspectRatio); }
test.h
#ifndef TEST_H #define TEST_H #include <QMainWindow> #include <QGraphicsView> #include <QGraphicsScene> class Test : public QMainWindow { Q_OBJECT public: explicit Test(QWidget* parent = nullptr); ~Test() override; void resizeEvent(QResizeEvent* event) override; public slots: private: QGraphicsView *m_view; QGraphicsScene *m_scene; }; #endif // TEST_H
And here is what I get when I start the application:
So clearly not what I am expecting.However, I get what I want when I resize the window:
The trick is done via the resizeEvent method. But I do not understand how can I do the same in the same in the constructor. Indeed
m_view->fitInView (m_scene->itemsBoundingRect(),Qt::IgnoreAspectRatio)
does not do the job when it is placed at the end of the constructor but works fine in resizeEvent.
Any idea?
-
@odelaune
Sizes are not always set/right in constructors in Qt. For example, debug out what is returned fromm_scene->itemsBoundingRect()
for that line where you call it in the constructor, my guess is it's not the size it will end up being?Size is only "correct" when the object has been shown, since that is when Qt can calculate/set it. So it would not be surprising if you have to redo this line in every
resizeEvent
.... -
@JonB said in QGraphicsScene does not fit QGraphicsView full size:
For example, debug out what is returned from m_scene->itemsBoundingRect() for that line where you call it in the constructor, my guess is it's not the size it will end up being?
Actually, they are the same (QRectF(-5,-5 472x349)) both in the constructor and in the resizeEvent function. The value doesn't change either when I resize the window (still QRectF(-5,-5 472x349)). The same with sceneRect().
-
@odelaune
But nonetheless you still say it does work when you do thefitInView()
in theresizeEvent()
, but not in the constructor, right??Then I would basically read it as:
fitInView()
does not work "at all" in constructor before the view/scene is really shown, and that's just how it is. Assuming it's good inresizeEvent()
you have your solution now anyway? (If it's still not right very first time when shown but noresizeEvent()
is called, you can do it initially inshowEvent()
too?) -
@JonB said in QGraphicsScene does not fit QGraphicsView full size:
@odelaune
But nonetheless you still say it does work when you do thefitInView()
in theresizeEvent()
, but not in the constructor, right??Yes, it does work in
resizeEvent()
.Then I would basically read it as:
fitInView()
does not work "at all" in constructor before the view/scene is really shown, and that's just how it is.It makes sense.
Assuming it's good in
resizeEvent()
you have your solution now anyway? (If it's still not right very first time when shown but noresizeEvent()
is called, you can do it initially inshowEvent()
too?)What was missing was the implementation of
showEvent()
. This is now done and it fits well, even when not resizing.Here is the working example code
test.cpp
// Qt headers #include <QPixmap> #include <QGraphicsPixmapItem> #include <QGraphicsRectItem> #include <QPainter> #include <QPen> #include <QDebug> #include <QResizeEvent> // Other headers #include "test.h" Test::Test(QWidget* parent /*=nullptr*/): QMainWindow(parent) { m_view = new QGraphicsView(this); // draw border of the QGraphicsView m_view->setStyleSheet("border: 5px solid red"); m_scene = new QGraphicsScene(m_view); m_view->setRenderHint(QPainter::Antialiasing, true); m_view->setScene(m_scene); m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QPixmap img("tmp.svg"); QGraphicsPixmapItem *item = m_scene->addPixmap(img); // draw border of the QGraphicsScene QGraphicsRectItem *rect_item = m_scene->addRect(m_scene->sceneRect()); rect_item->setParentItem(item); QPen pen = QPen(Qt::black); pen.setWidth(10); rect_item->setPen(pen); // set the mapView as the central widget setCentralWidget(m_view); m_view->show(); } // destructor Test::~Test() { } void Test::resizeEvent(QResizeEvent* event) { if(!m_scene) return; QRectF bounds = m_scene->itemsBoundingRect(); m_view->fitInView(bounds, Qt::IgnoreAspectRatio); } void Test::showEvent(QShowEvent* event) { if(!m_scene) return; QRectF bounds = m_scene->itemsBoundingRect(); m_view->fitInView(bounds, Qt::IgnoreAspectRatio); }
Thank you very much for your support.
-
@odelaune said in QGraphicsScene does not fit QGraphicsView full size:
What was missing was the implementation of showEvent(). This is now done and it fits well, even when not resizing.
Yes, For widgets it is
showEvent()
which is first called when it is shown. For anything "size" that is better than in constructor. -