How to obtain the correct position, width and height of a QGraphicsView in a dynamic widget

1.8k views Asked by At

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.

Screenshot showing the window while running this program

1

There are 1 answers

0
Serge45 On BEST ANSWER

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.