QPainter ou Graphics View : deux façons de dessiner avec Qt, deux usages différents
Pour dessiner avec Qt, la première décision n’est pas de choisir une couleur ou une forme, mais une architecture. Qt propose surtout 2 approches pour le dessin 2D : utiliser QPainter pour peindre directement sur une surface, ou passer par Graphics View pour manipuler des objets graphiques dans une scène. Les deux sont solides, mais elles ne répondent pas au même besoin.
Deux façons de penser le dessin 2D dans Qt
QPainter et Graphics View ne sont pas deux variantes interchangeables d’un même outil. QPainter est une API de dessin bas niveau : vous lui dites quoi tracer, où, avec quel stylo, quelle brosse et quelles transformations appliquer. Graphics View organise le dessin sous forme d’objets graphiques placés dans une scène, affichés par une vue.
Quiz : Dessin 2D avec Qt
La différence ressemble à celle entre peindre une affiche à la main et disposer des éléments mobiles sur un plan. Dans le premier cas, vous contrôlez chaque trait. Dans le second, vous gérez des entités qui peuvent être sélectionnées, déplacées, transformées ou recevoir des événements.
| Besoin | Approche conseillée | Pourquoi |
|---|---|---|
| Dessiner quelques formes dans un widget | QPainter | Simple, direct, adapté au rendu personnalisé |
| Afficher beaucoup d’objets interactifs | Graphics View | Architecture scène/vue/items prévue pour cela |
| Générer une image pixel par pixel | QImage avec QPainter ou accès pixels | QImage est adapté aux E/S et à la manipulation des pixels |
| Créer un éditeur de diagrammes ou de cartes | Graphics View | Gestion naturelle des éléments, événements et transformations |
| Imprimer ou produire un rendu vectoriel | QPainter sur QPrinter ou QSvgGenerator | Le même modèle de dessin peut cibler plusieurs surfaces |
Graphics View : scène, vue et éléments graphiques
Graphics View devient pertinent dès que le dessin se présente comme une collection d’objets. Au lieu de redessiner mentalement toute l’interface à chaque rafraîchissement, vous créez une scène, vous y ajoutez des éléments, puis une vue se charge de l’affichage. Cette séparation rend le code plus lisible pour les applications graphiques complexes.

QGraphicsScene, le conteneur intelligent
QGraphicsScene contient les éléments graphiques. Elle ne se limite pas à une liste de formes : elle participe aussi à la gestion des événements et de certains états. C’est elle qui sait quels objets sont présents, où ils se trouvent et comment ils interagissent dans l’espace de la scène.
Cette approche convient bien aux éditeurs de schémas, visualiseurs de réseaux, plans interactifs, interfaces de dessin technique ou outils pédagogiques. Si un utilisateur doit cliquer sur un objet, le déplacer, le sélectionner ou détecter une collision, Graphics View évite de tout reconstruire à la main.
QGraphicsView, la fenêtre sur la scène
QGraphicsView affiche le contenu d’une QGraphicsScene. La vue joue le rôle de caméra : elle montre une partie de la scène, peut gérer le défilement, le zoom ou des transformations d’affichage. Plusieurs vues peuvent même afficher la même scène, ce qui permet de proposer différents niveaux de zoom ou plusieurs angles de consultation.
Il faut bien distinguer la scène, qui représente le monde graphique, et la vue, qui représente la manière de le regarder. Cette séparation est l’un des avantages majeurs du modèle : elle évite de mélanger les données graphiques, leur comportement et leur rendu à l’écran.
QGraphicsItem, la base des objets dessinés
QGraphicsItem est la classe de base des éléments graphiques. Un item peut représenter une ligne, un rectangle, une ellipse, un texte, une image ou un objet personnalisé. Il peut aussi répondre aux événements souris et clavier, participer au drag and drop ou intégrer une logique de collision.
Quand vous créez vos propres items, vous définissez leur forme, leur zone englobante et leur manière de se peindre. C’est là que Graphics View rejoint QPainter : même dans une architecture objet, le rendu final d’un item repose souvent sur des opérations de peinture.
QPainter : peindre directement sur une surface Qt
QPainter est la classe centrale du dessin bas niveau dans Qt. Elle permet de tracer des formes, du texte, des images et des pixmaps sur tout objet dérivant de QPaintDevice. Derrière, QPaintEngine sert d’interface de rendu selon la cible utilisée.

QPaintDevice : la surface qui reçoit le dessin
Un QPainter ne dessine pas dans le vide. Il opère sur une surface : un QWidget, une QImage, une QPixmap, un QPrinter, un QSvgGenerator ou d’autres dispositifs spécialisés. Le choix de cette surface influence l’usage final.
QImage est particulièrement utile pour les entrées et sorties, ainsi que pour l’accès pixel par pixel. QPixmap est plutôt optimisé pour l’affichage à l’écran. QBitmap hérite de QPixmap. QPicture, lui, permet d’enregistrer puis de rejouer des commandes QPainter, pratique lorsqu’un rendu doit être conservé sous forme d’instructions.
paintEvent() : l’endroit naturel pour dessiner dans un widget
Dans un widget personnalisé, le dessin se fait généralement en redéfinissant paintEvent(). Cette méthode est appelée quand Qt estime que le widget doit être repeint : affichage initial, redimensionnement, zone invalidée, demande de mise à jour. C’est dans ce cadre que vous créez votre QPainter et que vous tracez les éléments nécessaires.
Évitez de dessiner directement depuis n’importe quelle méthode métier. À la place, modifiez l’état interne du widget, puis demandez un rafraîchissement. update() place une demande de rafraîchissement en file d’attente, ce qui laisse Qt regrouper les opérations efficacement. repaint() force un rafraîchissement immédiat. Il peut être utile dans certains cas précis, mais il est souvent moins souple.
Le rendu fonctionne un peu comme un mécanisme de distribution : si vous forcez chaque changement à passer tout de suite, le résultat devient heurté. En laissant update() transmettre la demande au bon moment, vous laissez Qt organiser le travail dans sa boucle d’événements. Le rendu est généralement plus fluide, surtout lorsque plusieurs changements visuels surviennent presque en même temps.
Formes, texte, images : ce que QPainter sait tracer
QPainter couvre les besoins classiques du dessin 2D : points, lignes, polygones, rectangles, ellipses, arcs, texte, pixmaps et images. Il travaille avec des stylos pour les contours, des brosses pour les remplissages, des polices pour le texte et des transformations pour modifier le repère de dessin.
Des primitives simples aux formes complexes
Pour un graphique simple, vous pouvez tracer des axes, des graduations, une courbe et des libellés avec QPainter. Pour un composant plus visuel, vous pouvez combiner rectangles arrondis, icônes, texte et zones colorées. Les primitives suffisent souvent pour créer des jauges, mini-cartes, aperçus, histogrammes ou visualisations internes.
Quand les formes deviennent plus élaborées, QPainterPath permet de construire des chemins complexes. Il sert à enchaîner segments, courbes et contours dans une même forme. C’est une bonne solution pour les icônes personnalisées, bulles, formes vectorielles ou zones cliquables au contour non rectangulaire.
Transformations, clipping et composition
Le dessin avec Qt ne se limite pas à poser des pixels. QPainter peut appliquer des transformations de coordonnées : translation, rotation, mise à l’échelle. Vous pouvez ainsi dessiner un objet dans son propre repère, puis déplacer ou agrandir ce repère plutôt que recalculer toutes les coordonnées à la main.
Le clipping limite le dessin à une zone donnée, utile pour éviter qu’un élément déborde. Les modes de composition contrôlent la manière dont les nouvelles formes se combinent avec ce qui est déjà dessiné. Ces mécanismes deviennent importants pour les superpositions, les masques, les effets de transparence ou les rendus techniques.
Bonnes pratiques pour éviter les erreurs classiques
La plupart des problèmes rencontrés lorsqu’on commence à dessiner avec Qt viennent d’un mauvais endroit de rendu ou d’un mauvais choix d’API. Une application peut fonctionner au début, puis devenir difficile à maintenir dès que le nombre d’objets, d’événements ou de surfaces augmente.
- Utilisez QPainter pour un widget personnalisé, un rendu ponctuel, une image générée ou un graphique simple.
- Utilisez Graphics View si vos éléments doivent vivre comme des objets, avec déplacement, sélection, collision et interaction.
- Dessinez dans paintEvent() pour les widgets, plutôt que dans le constructeur ou une méthode appelée au hasard.
- Préférez update() pour demander un rafraîchissement différé et laissez Qt optimiser la peinture.
- Réservez repaint() aux cas où un rendu immédiat est réellement nécessaire.
- Choisissez QImage pour manipuler des pixels et QPixmap pour un affichage écran efficace.
Le cas particulier des zones défilables
Avec les classes dérivées de QAbstractScrollArea, comme certaines vues ou zones à défilement, la surface réellement affichée n’est pas toujours le widget principal mais son viewport(). Si le dessin semble décalé, invisible ou effacé au mauvais moment, vérifiez que vous peignez bien sur la bonne cible.
Cette nuance est importante dans les interfaces avec scrollbars, vues personnalisées ou grands canevas. Le viewport représente la fenêtre visible sur le contenu. Dessiner sur lui, ou adapter correctement la logique de rendu à cette architecture, évite beaucoup de comportements surprenants.
Choisir l’API selon l’évolution du projet
Pour un prototype, QPainter dans un QWidget est souvent le chemin le plus rapide. Pour une application qui doit accueillir des dizaines ou des centaines d’objets manipulables, Graphics View offre une structure plus robuste. Le bon choix dépend moins de l’aspect du rendu que de la nature des éléments : simples tracés à recalculer, ou objets graphiques autonomes.
En pratique, les deux approches peuvent cohabiter. Graphics View organise les objets, QPainter réalise le rendu fin de certains items, et des surfaces comme QImage ou QPixmap servent de buffers, d’icônes ou d’exports. C’est cette combinaison qui fait de Qt un environnement efficace pour construire des interfaces 2D propres, interactives et durables.