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

What just happened?

Our new project is so simple that all its code is located in the main() function. Let's examine the code. First, we create a QApplication object, as in any Qt Widgets project. Next, we create a scene object and three instances of different item classes. The constructor of each item class accepts an argument that defines the content of the item:

  • The QGraphicsRectItem constructor receives a QRectF object that contains the coordinates of the rectangle
  • The QGraphicsEllipseItem constructor, similarly, receives a QRectF object that defines the bounding rectangle of the circle
  • The QGraphicsSimpleTextItem constructor receives the text to display
QRectF is basically a helpful struct with four fields that allow us to specify four coordinates of the rectangle's boundaries (left, top, width, and height). Qt also offers QPointF that contains x and y coordinates of a point, QLineF that contains x and y coordinates of two ends of a line, and QPolygonF that contains a vector of points. The F letter stands for "floating point" and indicates that these classes hold real numbers. They are widely used in Graphics View, as it always works with floating point coordinates. The corresponding classes without F ( QPoint, QRect, and so on) store integer coordinates and are more useful when working with widgets.

After creating each item, we use the QGraphicsScene::addItem function to add the item to the scene. Finally, we create a QGraphicsView object and pass the pointer to the scene to its constructor. The show() method will make the view visible, as it does for any QWidget. The program ends with an a.exec() call, necessary to start the event loop and keep the application alive.

The scene takes ownership of the items, so they will be automatically deleted along with the scene. This also means that an item can only be added to one single scene. If the item was previously added to another scene, it gets removed from there before it is added to the new scene.

If you want to remove an item from a scene without setting it directly to another scene or without deleting it, you can call scene.removeItem(rectItem). Be aware, however, that now it is your responsibility to delete rectItem to free the allocated memory!

Examine the resulting window and compare it to the coordinates of the rectangles in the code (the QRectF constructor we use accepts four arguments in the following order: left, top, width, height). You should be able to see that all three elements are positioned in a single coordinate system, where the x axis points to the right and the y axis points down. We didn't specify any coordinates for the text item, so it's displayed at the origin point (that is, the point with zero coordinates), next to the top-left corner of the rectangle. However, that (0, 0) point does not correspond to the top-left corner of the window. In fact, if you resize the window, you'll note that the origin has shifted relative to the window, because the view tries to display the scene's content as centered.