QTabWidget with QGraphicsView - c++

I have a QTabWidget and second page containing a QGraphicsView with scene. The scene canvas is larger than the QGraphicsView's viewport and I'm using QScrollBar to move objects on the scene.
On the scene I place a lot of QGraphicsItem objects. I have a horizontal and a vertical scroll bar, and some items can move only horizontally, another objects on scene can move only vertically.
My QGraphicsview coordinates start at the top left corner of QGraphicsview. After moving objects on the scene, if I change the page of the QTabWidget from second page to first and then back again, the start of coordinates is moved to the center of QGraphicsView, and all objects on the scene are moved to new positions automatically.
This happens only when I'm using a QTabWidget, if I change the parent of QGraphicsView to QWidget, all works well.

I found a solution. Just need to calculate rect of the scene, and set obviously using QGraphicsScene::setSceneRect() method. Otherwise, position of my scene in the QGraphicsView may surprise.

Related

QGraphicsView and QGraphicsScene coordinate systems

in Qt 4.8 i have create a QGraphicsView and a DynamicRadarScene(derived from QGraphicsScene):
QGraphicsView* view = new QGraphicsView;
view->setMinimumSize(800, 600);
DynamicRadarScene* _scene = new DynamicRadarScene(mode, channel_types, this);
view->setScene(_scene);
What is the coordinate system of QGraphicsScene? (0,0) is from upper left corner?
How can i draw an item in the upper right corner of the scene (i have set it 800x600: view->setMinimumSize(800, 600);)?
If i resize the widget and so i resize the QGraphicsView, how can move the item i have drawn before to remain in the upper left corner?
Yes, the upper left corner is generally the coordinate of (0,0) in a graphics scene. What you need to consider is that a QGraphicsView is like a window looking into a world (the QGraphicsScene). You set the view to look at an area or the scene, which may be all or just part of the scene.
Once the scene and view are setup, you can then add QGraphicsItems / QGraphicsObjects or instances of classes derived from those by using functions such as QGraphicsScene::addItem. These items are positioned in the scene and draw themselves.
i (sic) resize the widget and so i resize the QGraphicsView
You can change the QGraphicsView position and dimensions, but then the items in the scene will remain in the same place within the scene. Usually you would set up the scene and view and then move / resize the graphics items / objects within the scene, often with the setPos function: QGraphicsItem::setPos(). This sets the position of the item, relative to its parent. If the item has no parent, it sets the position of the item in the scene.
QGraphicsScene has property sceneRect. If it is not set then it is auto adjusted depending on scene content. This can give a filling that origin of coordinating is in some strange place or even that it is mobile.
Set this property. See also this.

QGraphicsView viewport rect problems

When I set the scene rect to the same rect of the viewport:
mCanvasScene->setSceneRect(mCanvasView->viewport()->rect());
The QGraphicsView creates scrollbars in the widget, but if the scene is the same size of the viewport why there are scrollbars ? It seems that the rect() from the viewport isn’t the correct size of the viewport area.
Does anyone knows how to set the scene with the same size of the visible area of the viewport ?
QGraphicsView inherits from QAbstractScrollArea, and viewport() returns widget managed by scroll area, which is usually bigger than the actual scroll area widget (reason for using scroll area in the first place).
Correct size of the visible area is the size of QGraphicsView (calling the inner widget viewport is little misleading).

Qt QGraphicsScene origin point

Whenever I add a new item to a QGraphicsScene, the origin of the QGraphicsScene seem to change for the position of the item I have just added.
How to make the QGraphicsScene origin fixed?
Do I need to add the item first in the QGraphicsScene and then specify a position for the item?
Well, by default the content of the scene will be centered in the QGraphicsView. The origin of the graphics scene does not change randomly.
You might want to use setSceneRect() to define the size of the scene, so that the QGraphicsView always centers the scene in the view in a fixed manner. (If you don't set it manually, the rect will be calculated based on the items in the scene, which changes if you add more.)
I answered a related question about a year ago that may be helpful:
How to draw a point (on mouseclick) on a QGraphicsScene?
Ditto to what badcat.
There are a lot of controls for adjusting or manipulating your viewport(s) that you have pointing at your scene. The scene sets what is on the stage. The view is how you look at it. Be sure to set the sceneRect or set it indirectly using centerOn or fitInView or scale or translate from the QGraphicsView class.
http://qt-project.org/doc/qt-4.8/graphicsview.html
http://qt-project.org/doc/qt-4.8/qgraphicsview.html
QGraphicsScene::setSceneRect ( const QRectF & rect ) will make it absolute.
see http://doc.qt.digia.com/qt/qgraphicsscene.html#sceneRect-prop

Anchoring a QGraphicsView to the corner of the screen

I have a QGraphicsView that renders my game. This view fills the entire screen at all times. In the top right I have another QGraphicsView which I'm using as a mini-map; it sits over the game view. I want this mini-map to be anchored to the top right of the screen, always maintaining its size. This code almost works, except that the left side of the mini-map never changes (which is to be expected).
void MainWindow::resizeEvent(QResizeEvent *event)
{
mainWindow->graphicsView->resize(event->size().width(), event->size().height());
QRect newRect(mainWindow->miniMapGraphicsView->geometry());
newRect.setRight(event->size().width() - 20);
mainWindow->miniMapGraphicsView->setGeometry(newRect);
}
How can I do this?
When you want to position widgets in a certain way, layouts are usually the best way to do it.
Add a QFormLayout to your graphicsView and set its layoutDirection to Qt::RightToLeft. Then add your miniMapGraphicsView to the layout. Editing the properties of the mini map, set its horizontal and vertical sizePolicy to Fixed and set its minimumSize and maximumSize to the dimensions you would like it to be.
An alternative would be to use a QGridLayout and use horizontal and vertical spacers to push the mini map to any corner of the view.
NOTE: Layouts have margins set by default so if you want your widgets to align snugly at the edges, zero them out.

Avoid automatic transition of QGraphicsScene on QGraphicsView

Qt's QGraphicsView has a habit of automatic transition/sliding of the view in such a way that everything drawn on the attached QGraphicsScene is visible. For example, suppose you've drawn something on the scene and viewing in the view. Now upon a button press you draw something along the right edge of the view. The scene/view will slide to the right slightly so that everything is again visible.
I want to prevent this to happen. How can I do that?
Thanks.
The scene rectangle of QGraphicsScene is by default the bounding rectangle of all the items in the scene. As such it grows when items are added.
The scene rectangle of QGraphicsView is by default taken from QGraphicsScene::sceneRect. If you don't want this to change automatically you can set one explicitly with QGraphicsView::setSceneRect.