Qt QGraphicsScene origin point - c++

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

Related

Qt: Custom QGraphicsItem not showing when boundingRect() center is out of view

I'm making a Diagram (Fluxogram) program and for days I'm stuck with this issue:
I have a custom QGraphicsScene that expands horizontally whenever I place an item to it's rightmost area. The problem is that my custom arrows (they inherit QGraphicsPathItem) disappear from the scene whenever it's boundingRect() center is scrolled off the view. Everytime the scene expands, both it's sceneRect() and the view's sceneRect() are updated as well.
I've:
set ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate)
the item flags QGraphicsItem::ItemIgnoresTransformations and QGraphicsItem::ItemSendsGeometryChanges, setActive(true) on the item as well, and everytime I add an arrow to the scene i call the update(sceneRect()) method. Still, everytime I scroll the view, as soon as the arrow's boundingRect() center moves away from the view, all the arrow disappears. If I scroll back and the boundingRect() center enters the view, all the arrow appears again.
Can someone give me a tip of what I might be missing? I've been using Qt's example project diagramscene as reference, so a lot of my code is similar (the "press item toolButton -> click on the scene" relation to insert items, the way they place the arrows to connect the objects,...).
In the meanwhile I'll try to make a minimal running example that can show what my issue is.
Your Arrow object inherits from QGraphicsPathItem, which I expect also implements the QGraphicsItem::shape function.
Override the shape function in your Arrow class, to return the shape of the item. This, along with the boundingRect is used to collision detection and detection of an item on-screen.
In addition, before changing the shape of an item by changing its boundingRect, you need to call prepareGeometryChange.
As the docs state: -
Prepares the item for a geometry change. Call this function before changing the bounding rect of an item to keep QGraphicsScene's index up to date.
So, in the Arrow class, store a QRectF called m_boundingRect and in the constructor: -
prepareGeometryChange();
m_boundingRect = QRectF(-x, -y, x*2, y*2);
Then return m_boundingRect in the boundingRect() function.
If this is still an issue, I expect it's something in QGraphicsPainterPath that's causing the problem, in which case, you can simply inherit from QGraphicsItem and store a QPainterPath with which you draw in the item's paint function and also return the painter path in shape().
You are making your life too complicated. Do not subclass QGraphicsPathItem just use it and update its path value every time position of anchors (from to) changes.

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.

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.

Qt - QGraphicsView without ScrollBar

I am trying to show a picture in it's full view using QGraphicsScene. But when ever I put the QgraphicsScene inside the QGraphicsView, I am getting a scroll bar. I tried so many ways But all are went to veins. So can anybody tell me how to obtain the full view without the scrollbar.
You might be getting scrollbars because the scene is larger than the usable area within the graphics view. By default, a QGraphicsView comes with a 1-pixel margin. To fix this, you can try:
QRect rcontent = graphicsView.contentsRect();
graphicsView.setSceneRect(0, 0, rcontent.width(), rcontent.height());
I had been getting scrollbars because I was manually setting the scene rect to the size of the graphics item I was adding -- which was as large as the QGraphicsView widget. I wasn't taking into account the margin.
QGraphicsView v;
v.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
v.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
To adjust the scrolling programmatically once these have been hidden, use one of the overloads of v.ensureVisible().