I have a QGraphicsView element inside a QHorizontalLayout inside a QVerticalLayout, so that if the screen is resized, the graphicsview element is resized with it. In Qt Creator any element you add to this construction will have no geometry data attached to it. In Qt Creator it is grayed out, and dynamically updated.
When I try to get the size of this graphicsView element via c++ it will however return the default values (0,0 100x30), not the actual width and height as how it is displayed on the screen. How do I get the correct position, width and height from this QGraphicsView element?
Minimal program to reproduce this problem
Default qt widget with the following changes:
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGraphicsView" name="graphicsView"/>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QGraphicsScene>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Expected output: 1 1 380 280
//Actual output: 0 0 100 30
qDebug() << ui->graphicsView->x() << ui->graphicsView->y()
<< ui->graphicsView->width() << ui->graphicsView->height();
//Expected output: QRectF(1,1 380x280)
//Actual output: QRectF(0,0 100x30)
qDebug() << ui->graphicsView->rect();
//We need a scene to draw things
QGraphicsScene *scene = new QGraphicsScene( parent );
ui->graphicsView->setScene(scene);
scene->setSceneRect(ui->graphicsView->x(), ui->graphicsView->y(),
ui->graphicsView->width(), ui->graphicsView->height());
//Box in the top left and bottom right so we have a visual clue
scene->addRect(0,0,2,2,QPen(),QBrush());
scene->addRect(scene->width(),scene->height(),2,2,QPen(),QBrush());
}
MainWindow::~MainWindow()
{
delete ui;
}
Screenshot of the program.
The two little rectangles are the top-left and bottom-right of the scene, which is set to the position and size of the QGraphicsView. The scene is displayed in the middle, because scenes smaller than the QGraphicsView they are in are centered, which means that the application is somehow aware of the actual size of the QGraphicsView. The area between those rectangles is 100 by 30 pixels, which seems to be the default value.
If a QWidget is hidden, it won't receive
QResizeEvent
until it is shown, see https://qt-project.org/doc/qt-5/qwidget.html#size-prop. So when you try to get the position or size in the constructor, you'll get the default values.You can monitor the geometry of your graphicsView in the
void resizeEvent(QResizeEvent *)
of you MainWindow.