Exemple de peinture en 2D
L'exemple de peinture 2D montre comment les classes QPainter et QOpenGLWidget peuvent être utilisées conjointement pour afficher des graphiques 2D accélérés sur le matériel pris en charge.

La classe QPainter est utilisée pour dessiner des primitives graphiques 2D sur des périphériques de peinture fournis par les sous-classes de QPaintDevice, telles que QWidget et QImage.
Comme QOpenGLWidget est une sous-classe de QWidget, il est possible de réimplémenter sa classe paintEvent() et d'utiliser QPainter pour dessiner sur le périphérique, comme vous le feriez avec QWidget. La seule différence est que les opérations de peinture seront accélérées au niveau matériel si elles sont prises en charge par les pilotes OpenGL de votre système.
Dans cet exemple, nous effectuons les mêmes opérations de peinture sur un QWidget et un QOpenGLWidget. Le QWidget est représenté avec l'anticrénelage activé, et le QOpenGLWidget utilisera également l'anticrénelage si les extensions requises sont prises en charge par le pilote OpenGL de votre système.
Vue d'ensemble
Pour pouvoir comparer les résultats de la peinture sur une sous-classe QOpenGLWidget avec le dessin natif dans une sous-classe QWidget, nous voulons montrer les deux types de widgets côte à côte. Pour ce faire, nous dérivons des sous-classes de QWidget et QOpenGLWidget, en utilisant une classe Helper distincte pour effectuer les mêmes opérations de peinture pour chacune d'entre elles, et nous les disposons dans un widget de niveau supérieur, lui-même fourni par la classe Window.
Définition de la classe d'aide
Dans cet exemple, les opérations de peinture sont effectuées par une classe d'aide. En effet, nous voulons que les mêmes opérations de peinture soient effectuées à la fois pour notre sous-classe QWidget et pour la sous-classe QOpenGLWidget.
La classe Helper est minimale :
class Helper { public: Helper(); public: void paint(QPainter *painter, QPaintEvent *event, int elapsed); private: QBrush background; QBrush circleBrush; QFont textFont; QPen circlePen; QPen textPen; };
En dehors du constructeur, elle ne fournit qu'une fonction paint() pour peindre à l'aide d'un peintre fourni par l'une de nos sous-classes de widgets.
Mise en œuvre de la classe d'aide
Le constructeur de la classe met en place les ressources nécessaires pour peindre le contenu sur un widget :
Helper::Helper() { QLinearGradient gradient(QPointF(50, -20), QPointF(80, 20)); gradient.setColorAt(0.0, Qt::white); gradient.setColorAt(1.0, QColor(0xa6, 0xce, 0x39)); background = QBrush(QColor(64, 32, 64)); circleBrush = QBrush(gradient); circlePen = QPen(Qt::black); circlePen.setWidth(1); textPen = QPen(Qt::white); textFont.setPixelSize(50); }
La peinture proprement dite est réalisée par la fonction paint(). Celle-ci prend un QPainter qui a déjà été configuré pour peindre sur un dispositif de peinture (soit un QWidget ou un QOpenGLWidget), un QPaintEvent qui fournit des informations sur la région à peindre, et une mesure du temps écoulé (en millisecondes) depuis la dernière mise à jour du dispositif de peinture.
void Helper::paint(QPainter *painter, QPaintEvent *event, int elapsed) { painter->fillRect(event->rect(), background); painter->translate(100, 100);
Nous commençons à peindre en remplissant la région contenue dans l'événement de peinture avant de translater l'origine du système de coordonnées afin que le reste des opérations de peinture soit déplacé vers le centre du dispositif de peinture.
Nous dessinons une spirale de cercles, en utilisant le temps écoulé spécifié pour les animer de sorte qu'ils semblent se déplacer vers l'extérieur et autour de l'origine du système de coordonnées :
painter->save(); painter->setBrush(circleBrush); painter->setPen(circlePen); painter->rotate(elapsed * 0.030); qreal r = elapsed / 1000.0; int n = 30; for (int i = 0; i < n; ++i) { painter->rotate(30); qreal factor = (i + r) / n; qreal radius = 0 + 120.0 * factor; qreal circleRadius = 1 + factor * 20; painter->drawEllipse(QRectF(radius, -circleRadius, circleRadius * 2, circleRadius * 2)); } painter->restore();
Comme le système de coordonnées subit de nombreuses rotations au cours de ce processus, nous save() l'état de QPainter avant et restore() après.
painter->setPen(textPen); painter->setFont(textFont); painter->drawText(QRect(-50, -50, 100, 100), Qt::AlignCenter, QStringLiteral("Qt")); }
Nous dessinons du texte à l'origine pour compléter l'effet.
Définition de la classe Widget
La classe Widget fournit un widget personnalisé de base que nous utilisons pour afficher l'animation simple peinte par la classe Helper.
class Helper; class Widget : public QWidget { Q_OBJECT public: Widget(Helper *helper, QWidget *parent); public slots: void animate(); protected: void paintEvent(QPaintEvent *event) override; private: Helper *helper; int elapsed; };
En dehors du constructeur, elle ne contient qu'une fonction paintEvent(), qui nous permet de dessiner un contenu personnalisé, et un slot qui est utilisé pour animer son contenu. Une variable membre garde la trace de Helper que le widget utilise pour peindre son contenu, et l'autre enregistre le temps écoulé depuis sa dernière mise à jour.
Mise en œuvre de la classe Widget
Le constructeur initialise uniquement les variables membres, stocke l'objet Helper fourni et appelle le constructeur de la classe de base, et impose une taille fixe au widget :
Widget::Widget(Helper *helper, QWidget *parent) : QWidget(parent), helper(helper) { elapsed = 0; setFixedSize(200, 200); }
Le slot animate() est appelé à chaque fois qu'une minuterie, que nous définirons plus tard, s'arrête :
void Widget::animate() { elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000; update(); }
Nous déterminons ici l'intervalle qui s'est écoulé depuis le dernier arrêt de la minuterie et nous l'ajoutons à toute valeur existante avant de repeindre le widget. Étant donné que l'animation utilisée dans la classe Helper boucle toutes les secondes, nous pouvons utiliser l'opérateur modulo pour nous assurer que la variable elapsed est toujours inférieure à 1000.
Étant donné que la classe Helper effectue toutes les opérations de peinture, il nous suffit d'implémenter un événement de peinture qui met en place une QPainter pour le widget et appelle la fonction paint() de l'assistant :
void Widget::paintEvent(QPaintEvent *event) { QPainter painter; painter.begin(this); painter.setRenderHint(QPainter::Antialiasing); helper->paint(&painter, event, elapsed); painter.end(); }
Définition de la classe GLWidget
La définition de la classe GLWidget est fondamentalement la même que celle de la classe Widget, sauf qu'elle est dérivée de QOpenGLWidget.
class Helper; class GLWidget : public QOpenGLWidget { Q_OBJECT public: GLWidget(Helper *helper, QWidget *parent); public slots: void animate(); protected: void paintEvent(QPaintEvent *event) override; private: Helper *helper; int elapsed; };
Là encore, les variables membres enregistrent le site Helper utilisé pour peindre le widget et le temps écoulé depuis la dernière mise à jour.
Mise en œuvre de la classe GLWidget
Le constructeur diffère légèrement de celui de la classe Widget:
GLWidget::GLWidget(Helper *helper, QWidget *parent) : QOpenGLWidget(parent), helper(helper) { elapsed = 0; setFixedSize(200, 200); setAutoFillBackground(false); }
La variable membre elapsed est initialisée et l'objet Helper utilisé pour peindre le widget est stocké.
Le slot animate() est exactement le même que celui fourni par la classe Widget:
void GLWidget::animate() { elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000; update(); }
L'emplacement paintEvent() est presque identique à celui de la classe Widget:
void GLWidget::paintEvent(QPaintEvent *event) { QPainter painter; painter.begin(this); painter.setRenderHint(QPainter::Antialiasing); helper->paint(&painter, event, elapsed); painter.end(); }
Étant donné que l'anticrénelage sera activé s'il est disponible, il nous suffit de configurer un QPainter sur le widget et d'appeler la fonction paint() de l'assistant pour afficher le contenu du widget.
Définition de la classe de fenêtre
La classe Window a une définition basique et minimale :
class Window : public QWidget { Q_OBJECT public: Window(); private: Helper helper; };
Elle contient un seul objet Helper qui sera partagé par tous les widgets.
Mise en œuvre de la classe Window
Le constructeur fait tout le travail, en créant un widget de chaque type et en les insérant avec des étiquettes dans une disposition :
Window::Window() { setWindowTitle(tr("2D Painting on Native and OpenGL Widgets")); Widget *native = new Widget(&helper, this); GLWidget *openGL = new GLWidget(&helper, this); QLabel *nativeLabel = new QLabel(tr("Native")); nativeLabel->setAlignment(Qt::AlignHCenter); QLabel *openGLLabel = new QLabel(tr("OpenGL")); openGLLabel->setAlignment(Qt::AlignHCenter); QGridLayout *layout = new QGridLayout; layout->addWidget(native, 0, 0); layout->addWidget(openGL, 0, 1); layout->addWidget(nativeLabel, 1, 0); layout->addWidget(openGLLabel, 1, 1); setLayout(layout); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, native, &Widget::animate); connect(timer, &QTimer::timeout, openGL, &GLWidget::animate); timer->start(50); }
Un minuteur avec un délai de 50 millisecondes est construit à des fins d'animation et connecté aux emplacements animate() des objets Widget et GLWidget. Une fois lancés, les widgets devraient être mis à jour à une vitesse d'environ 20 images par seconde.
Exécution de l'exemple
L'exemple montre les mêmes opérations de peinture effectuées en même temps dans un Widget et un GLWidget. La qualité et la vitesse du rendu dans le GLWidget dépendent du niveau de prise en charge du multi-échantillonnage et de l'accélération matérielle fournis par le pilote OpenGL de votre système. Si la prise en charge de l'un ou l'autre de ces éléments fait défaut, le pilote peut se rabattre sur un moteur de rendu logiciel qui peut sacrifier la qualité à la vitesse.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.