Chapter 21. Graphics View

Ever faced a situation where dozens of graphical objects start to “lag”, overlap each other, and behave unpredictably? Every developer working with interactive graphics eventually hits this chaos — especially when scaling, rotations, collisions, and real-time event handling are required.

This chapter gradually reveals how to transform a chaotic 2D scene into a manageable, scalable system. You’ll discover why professional developers bet not on manual repainting but on an architecture capable of handling thousands and even millions of elements without extra effort. The before/after contrast is immediately felt: less code — more control, higher performance, and cleaner logic.

We’ll examine QGraphicsScene, QGraphicsView, and QGraphicsItem, working with element hierarchies, basic transformations, and several collision detection modes — from fast to precise. Practical examples show how the same object can be displayed in multiple views and respond to events without manual repaint management.

Skipping this chapter — risks staying forever in a world of workarounds and unnecessary optimizations.

This chapter includes ready-to-use code examples.

Chapter Self-Check

What role does each of the three main graphics view classes play in Qt’s architecture?Answer
Correct answer: QGraphicsScene is the model-container for graphical elements, QGraphicsView — the view for their visualization with scroll bars, QGraphicsItem — the abstract base class for creating scene elements.
Why is the QGraphicsItem class abstract and which methods must be implemented when creating a custom element?Answer
Correct answer: QGraphicsItem is abstract to provide flexibility for different types of elements. When inheriting, you must implement paint() for rendering and boundingRect() for defining element boundaries.
Why does the scene divide area into sub-regions before sending the changed() signal?Answer
Correct answer: Dividing into sub-regions allows analyzing exactly which parts were changed and repainting only them. This ensures high performance in real-time mode even for millions of elements.
Why is separating data (QGraphicsScene) from view (QGraphicsView) an advantage of the architecture?Answer
Correct answer: This allows displaying the same scene in several different view widgets, provides automatic repainting on changes, and more efficiently uses CPU and memory resources.
How are mouse and keyboard events transferred from the view to individual scene elements?Answer
Correct answer: The view receives events, converts them to scene events with scene coordinates, then the scene automatically translates coordinates to local coordinates of a specific element and passes the event to it.
Why do child elements move along with parent element when the parent moves?Answer
Correct answer: Because each element has a local coordinate system relative to its parent, and any parent transformation is automatically applied to all its children.
Why is it necessary to override the boundingRect() method when creating a custom element?Answer
Correct answer: The boundingRect() method is needed by the view to determine invisible elements, calculate non-overlapped areas for repainting, and for correct collision detection mechanism operation.
What’s the fundamental difference between QGraphicsSimpleTextItem and QGraphicsTextItem?Answer
Correct answer: QGraphicsSimpleTextItem is designed for fast display of simple text with low memory consumption, while QGraphicsTextItem supports formatted text with document editing capability.
How do you make an element draggable with the mouse and which methods are called in the process?Answer
Correct answer: You need to call setFlags(QGraphicsItem::ItemIsMovable). During movement, mousePressEvent(), mouseMoveEvent(), and mouseReleaseEvent() are automatically called, which can be overridden for additional processing.
What is the collidesWithItem() method for and what collision detection modes exist?Answer
Correct answer: The method determines element collisions. Modes: IntersectsItemShape (shape intersection), ContainsItemShape (full containment), IntersectsItemBoundingRect (fast rectangle check), and ContainsItemBoundingRect.
Why might calling setViewport(new QOpenGLWidget) for a view be needed?Answer
Correct answer: This allows using OpenGL for hardware-accelerated scene rendering, significantly improving performance when working with complex graphics or large numbers of elements.
Why do widgets placed in the scene via QGraphicsProxyWidget maintain their functionality?Answer
Correct answer: Thanks to the event mechanism, widgets continue to receive and process user actions, while geometric transformations can be applied to them like regular scene elements.
When is using graphics view preferable to directly placing widgets?Answer
Correct answer: When working with large numbers of graphical elements requiring transformations, collision detection, grouping, and real-time management — graphics view uses resources more efficiently.
What three main transformations does the QTransform class provide and how are they applied to elements?Answer
Correct answer: QTransform provides translate() (shift), rotate() (rotation), and scale() (scaling). Transformations are applied to an element by calling setTransform() with a QTransform object.
What will happen if you try to create multiple QGraphicsScene objects and display them in one view?Answer
Correct answer: Only one scene can be displayed in one view — the last one set via setScene() replaces the previous one. However, one scene can be displayed in multiple views simultaneously.

Practical Exercises

Easy Level

Interactive Shape Gallery
Create an application with a graphics view featuring 5 different geometric shapes (rectangle, ellipse, line, polygon, text). All elements should be draggable with mouse and have different fill colors. Add buttons to zoom in and out of the view.
Hints: Use scene.addRect(), addEllipse(), addLine(), addPolygon(), addText() methods to create elements. For each element, call setFlags(QGraphicsItem::ItemIsMovable). The view’s scale() method allows changing zoom. Don’t forget to set colors via QPen and QBrush.

Medium Level

Collision Detector with Visualization
Create a scene with two rectangles of different colors that can be moved with mouse. Implement collision detection: when rectangles intersect, they should change color to red, and return to original colors when not intersecting. Add a text label showing collision status (“Collision” or “No Collision”).
Hints: Create custom element class inherited from QGraphicsRectItem. Override mouseMoveEvent() methods for collision checking. Use collidesWithItem() to determine intersections. Store pointers to both elements for mutual checking. Update colors via setBrush() and label text via setText().

Hard Level

Hierarchical Solar System with Animation
Develop an interactive solar system model: central sun (circle) around which 3 planets (smaller circles) rotate. Each planet should have 1-2 satellites rotating around it. Use parent-child hierarchy for linking elements. Implement rotation animation using QTimer and rotate() methods. Add control widgets: animation speed slider, pause/play buttons, and reset to initial position button.
Hints: Create sun as root element. Add planets via setParentItem(sun), satellites — via setParentItem(planet). For rotation, use QTimer with ~16ms interval and in slot call setRotation() with increment. Each element rotates relative to its local coordinate system. Add widgets via QGraphicsProxyWidget. Save initial positions for reset function.

💬 Join the Discussion!

Mastered the graphics view architecture? Have questions about working with QGraphicsScene or implementing collision detection?

Share your projects with graphics view, tell us about challenges working with transformations, or help others understand element hierarchy!

Leave a Reply

Your email address will not be published. Required fields are marked *