1

I have an application composed from graphics view and graphics scene. The basic GUI structure is this (done in Qt Creator):

QMainWindow
  QWidget (centralWidget)
    QGridLayout
      QVBoxLayout
      QGraphicsView

This is my code for the mainwindow constructor:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
{
    ui->setupUi(this);

    scene = new Scene(this);
    ui->graphicsView->setScene(scene);
    scene->setSceneRect(-100,-100,200,200);
}

Now when I manually resize the application window, visually the scene/graphics view resizes too. It is also active in all the visible area, I can catch mouse events, add items there, although it is out of the region set by setSceneRect(). But when I call scene->width() or scene->height(), it returns 200 all the time. How can I get the size of the visible part of the scene and not the size set in setSceneRect()? By the visible part of the scene I mean the white visible area/rectangle where my items are visualized, if the item goes out of this area, it is not visible.

T.Poe
  • 1,949
  • 6
  • 28
  • 59
  • It seems tha this is what I was looking for: `graphicsView->mapToScene(graphicsView->viewport()->geometry()).boundingRect()`, in case anybody needs that. – T.Poe Mar 15 '18 at 15:59
  • When you get time, please post your comment as an answer to your own question. – drescherjm Mar 15 '18 at 16:35

1 Answers1

0

There's generally no need to use set the scene rectangle at all, unless the scene has very many items. Setting it is an optimization when you can calculate the bounding rectangle of the scene's contents faster than itemsBoundingRect() can, or if you know the fixed maximum size of the scene- e.g. if the scene represents some fixed-size canvas. Otherwise, you have no recourse but to leave it unset.

Anyway, binding the scene rectangle to the viewport is incorrect. The scene rectangle is used by the spatial index and must represent the contents of the scene, irrespectively of any viewports. Recall that the scene is a model usable by itself - it can have 0 or more viewports attached to it. Binding any particular viewport strongly to any of the scene's parameters is a design error.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thanks for your answer. I had to set the scene rectangle (or at least didn't find any other solution). The problem was that I have several small graphic items moving in the scene. If one of them came too close to the border of the visible part of the scene, the whole scene moved, so the item was no more close to the border, but its coordinates remained the same, only the scene itself with all the items together moved. I fixed it with `setSceneRect()`. To the other part, so how should I get the size of this visible part of the scene if my solution in the comment is wrong? – T.Poe Mar 16 '18 at 08:41
  • You can set the alignment of the scene in the view; e.g. you'd want the top-left corner to be mapped to the same point between the viewport and the scene. Then nothing will move. – Kuba hasn't forgotten Monica Mar 16 '18 at 18:49
  • Thanks for the suggestions, but setting the alignment still has some issues. The scene moves during adding the first item, then it's ok. But that's probably for another question about how to properly set the alignment and prevent the mentioned issue. – T.Poe Mar 19 '18 at 15:05