Game Programming using Qt 5 Beginner's Guide
上QQ阅读APP看书,第一时间看更新

The viewport's coordinate system

The view consists of the viewport and two scrollbars. The viewport is a subwidget that actually contains the content of the scene. The view performs conversion from the scene coordinates to the viewport coordinates based on multiple parameters.

First, the view needs to know the bounding rectangle of everything we could want to see in the scene. It's called the scene rect and is measured in the scene's coordinate system. By default, the scene rect is the bounding rectangle of all items that were added at the scene since it was created. This is usually fine, but if you move or delete an item, that bounding rectangle will not shrink (because of performance reasons), so it may result in showing a lot of unwanted empty space. Luckily, in such cases, you can set the scene rect manually using the setSceneRect function of the scene or view.

The difference between QGraphicsScene::setSceneRect and QGraphicsView::setSceneRect is usually marginal, since you will typically have one view per scene. However, it is possible to have multiple views for a single scene. In this case, QGraphicsScene::setSceneRect sets the scene rect for all views, and QGraphicsView::setSceneRect allows you to override the scene rect for each view.

If the area corresponding to the scene rect is small enough to fit in the viewport, the view will align the content according to the view's alignment property. As we saw earlier, it positions the content at the center by default. For example, calling view.setAlignment(Qt::AlignTop | Qt::AlignLeft) will result in the scene staying in the upper-left corner of the view.

If the scene rect area is too large to fit in the viewport, the horizontal or vertical scrollbars appear by default. They can be used to scroll the view and see any point inside the scene rect (but not beyond it). The presence of scrollbars can also be configured using the  horizontalScrollBarPolicy and the verticalScrollBarPolicy properties of the view.

Try to call scene.setSceneRect(0, 20, 100, 100) and see how the view acts when resizing the window. If the window is too small, the top part of the scene will no longer be visible. If the window is large enough and the view has the default alignment, the top part of the scene will be visible, but only the defined scene rect will be centered, with no regard to the items outside of it.

The view provides the ability to transform the entire scene. For example, you can call view.scale(5, 5) to make everything five times larger, view.rotate(20) to rotate the scene as a whole, or view.shear(1, 0) to shear it. As with items, you can apply a more complex transformation using setTransform().

You may note that Graphics View (and Qt Widgets in general) uses a  left-handed coordinate system by default, where  x axis points right and y axis points down. However, OpenGL and science-related applications usually use a  right-handed or standard coordinate system, where y axis points up. If you need to change the direction of the y axis, the simplest solution is to transform the view by calling view.scale(1, -1).