What just happened?

First, you determined the rectangle of the scene with sceneRect(). Since this returns a QRectF parameter and QImage can only handle QRect, you transformed it on the fly by calling toAlignedRect(). The difference between the toRect() function and toAlignedRect() is that the former rounds to the nearest integer, which may result in a smaller rectangle, whereas the latter expands to the smallest possible rectangle containing the original QRectF parameter.

Then, you created a QImage file with the size of the aligned scene's rectangle. As the image is created with uninitialized data, you need to call fill() with Qt::transparent to receive a transparent background. You can assign any color you like as an argument both as a value of Qt::GlobalColor enumeration and an ordinary QColor object; QColor(0, 0, 255) will result in a blue background. Next, you create a QPainter object that points to the image. This painter object is then used in the scene's render() function to draw the scene. After that, all you have to do is use the save() function to save the image to a place of your choice. The format of the output file is determined by its extension. Qt supports a variety of formats, and Qt plugins can add support for new formats. Since we haven't specified a path, the image will be saved in the application's working directory (which is usually the build directory, unless you changed it using the Projects pane of Qt Creator). You can also specify an absolute path, such as /path/to/image.png.

Of course, you'll need to construct a path that's valid on the current system instead of hard-coding it in the sources. For example, you can use the  QFileDialog::getSaveFileName() function to ask the user for a path.