Introduction
Qt’s Graphics View Framework (QGraphicsView, QGraphicsScene, QGraphicsItem) is widely used for building real-time 2D visualization systems such as radar displays, tactical maps, UAV monitoring dashboards, and simulation tools.
In this article, we walk through how a radar-like 2D track display is implemented using Qt GraphicsScene, including:
- Static polar grid (range rings & bearings)
- Dynamic moving tracks
- Velocity vectors and short trails
- Zoom-independent symbols and labels
Only key code fragments are shown to explain the technique—not a full application.
Why Qt GraphicsScene?
Qt GraphicsScene is ideal when you need:
- High-frequency updates (10–60 Hz)
- Large numbers of moving objects
- Layer-based rendering
- Interactive graphics items
- Clean separation of logic and visualization
This makes it a natural choice for radar, defense, aviation, and GIS-based systems.
Scene Initialization
At the core is a QGraphicsScene attached to a custom QGraphicsView:
m_scene = new QGraphicsScene(this);
setScene(m_scene);
The scene uses logical coordinates (meters or kilometers), not screen pixels, which simplifies real-world mapping.
Static Layer: Polar Grid & Range Rings
The static layer is created once and rarely updated.
It typically includes concentric rings, bearing lines, and distance labels.
Creating a Static Layer Group
m_staticLayer = new QGraphicsItemGroup();
m_scene->addItem(m_staticLayer);
Drawing Range Rings (Key Fragment)
QPen ringPen(QColor(180, 180, 180));
ringPen.setCosmetic(true); // constant line width
auto *ring = new QGraphicsEllipseItem(-r, -r, 2*r, 2*r);
ring->setPen(ringPen);
ring->setBrush(Qt::NoBrush);
m_staticLayer->addToGroup(ring);
Distance Labels (Zoom-Safe)
auto *label = new QGraphicsTextItem("50 km");
label->setFlag(QGraphicsItem::ItemIgnoresTransformations);
label->setPos(r + 4, -4);
m_staticLayer->addToGroup(label);
Bearing Lines (Every 30°)
double rad = qDegreesToRadians(angleDeg);
QPointF end(radius * qCos(rad), radius * qSin(rad));
auto *line = new QGraphicsLineItem(0, 0, end.x(), end.y());
line->setPen(ringPen);
m_staticLayer->addToGroup(line);
This produces the familiar radar polar grid.
Dynamic Tracks: Targets on the Map
Each moving target is represented by:
- A blip (ellipse)
- A text label (track ID)
- A velocity vector
- A short movement trail
Creating Track Graphics (Once)
auto *trackItem = new QGraphicsEllipseItem(-4, -4, 8, 8);
trackItem->setFlag(QGraphicsItem::ItemIgnoresTransformations);
m_scene->addItem(trackItem);
auto *trackLabel = new QGraphicsTextItem(QString::number(trackId));
trackLabel->setFlag(QGraphicsItem::ItemIgnoresTransformations);
m_scene->addItem(trackLabel);
Updating Track Position
Track updates happen whenever new data arrives from sensors, simulators, or network feeds.
QPointF pos = convertLatLonToScene(lat, lon);
trackItem->setPos(pos);
trackLabel->setPos(pos + QPointF(6, -6));
The conversion function maps real-world coordinates to scene coordinates.
Velocity Vector (Heading Indicator)
Velocity vectors show direction of motion and remain visually consistent across zoom levels.
double angleRad = qDegreesToRadians(headingDeg);
double sceneLen = screenPixels / transform().m11();
QPointF v(sceneLen * qSin(angleRad),
-sceneLen * qCos(angleRad));
velocityLine->setLine(pos.x(), pos.y(),
pos.x() + v.x(), pos.y() + v.y());
This ensures the vector length stays constant on screen, not in scene units.
Track Trails (Recent History)
Trails help operators understand movement patterns.
history.append({pos, timestamp});
while (!history.isEmpty() &&
now - history.front().time > 5000)
history.pop_front();
Rendering the Trail Path
QPainterPath path;
path.moveTo(history.first().pos);
for (int i = 1; i < history.size(); ++i)
path.lineTo(history[i].pos);
trailItem->setPath(path);
Only the last few seconds are kept for performance.
Interaction Support
Each track can support interaction:
trackItem->setFlag(QGraphicsItem::ItemIsSelectable);
trackItem->setAcceptHoverEvents(true);
This enables:
- Tooltips
- Context menus
- Track designation changes
- Selection and highlighting
Advantages of This Design
✔ Performance-Friendly
Static grid drawn once, only tracks update
✔ Scalable
Handles hundreds or thousands of targets
✔ Clean Architecture
Separate layers for grid, tracks, and overlays
✔ Professional UI
Zoom-safe symbols and consistent visuals
Conclusion
Qt GraphicsScene offers a mature, production-ready framework for building radar-like 2D tracking displays. By combining static polar grids, dynamic track items, velocity vectors, and trails, developers can create high-performance tactical views without resorting to heavy OpenGL pipelines.
This approach is proven in defense, aviation, drone, and simulation systems, and integrates easily with real-time data feeds, GIS backends, and playback engines.
Need Similar Qt-Based Visualization Software?
Manya Technologies specializes in:
- Qt C++ real-time applications
- Radar & tactical display systems
- Custom GIS viewers (QGIS / PostGIS)
- Simulation and tracking software
🌐 Website: https://manyatechnologies.com
If you’re building a custom radar, drone, or tracking visualization, we can design and deliver a robust, scalable solution tailored to your needs.

