Exemple de gestes d'image
Démontre l'utilisation de gestes simples dans un widget.
Cet exemple montre comment activer les gestes pour un widget et utiliser la saisie gestuelle pour effectuer des actions.

Nous utilisons deux classes pour créer l'interface utilisateur de l'application : MainWidget et ImageWidget. La classe MainWidget sert simplement de conteneur pour la classe ImageWidget, que nous allons configurer pour accepter les entrées gestuelles. Comme nous nous intéressons à la manière dont les gestes sont utilisés, nous nous concentrerons sur l'implémentation de la classe ImageWidget.
Définition de la classe ImageWidget
La classe ImageWidget est une simple sous-classe de QWidget qui réimplémente la fonction générale QWidget::event() handler en plus de plusieurs gestionnaires d'événements plus spécifiques :
class ImageWidget : public QWidget { Q_OBJECT public: ImageWidget(QWidget *parent = nullptr); void openDirectory(const QString &url); void grabGestures(const QList<Qt::GestureType> &gestures); protected: bool event(QEvent *event) override; void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; private: bool gestureEvent(QGestureEvent *event); void panTriggered(QPanGesture*); void pinchTriggered(QPinchGesture*); void swipeTriggered(QSwipeGesture*); ... };
Nous implémentons également une fonction d'aide privée, gestureEvent(), pour aider à gérer les événements gestuels transmis au widget, ainsi que trois fonctions permettant d'effectuer des actions basées sur les gestes : panTriggered(), pinchTriggered() et swipeTriggered().
Mise en œuvre de la classe ImageWidget
Dans le constructeur du widget, nous commençons par définir divers paramètres qui seront utilisés pour contrôler la manière dont les images sont affichées.
ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent), position(0), horizontalOffset(0), verticalOffset(0) , rotationAngle(0), scaleFactor(1), currentStepScaleFactor(1) { setMinimumSize(QSize(100, 100)); }
Nous activons trois des gestes standard pour le widget en appelant QWidget::grabGesture() avec les types de gestes dont nous avons besoin. Ceux-ci seront reconnus par l'outil de reconnaissance de gestes par défaut de l'application, et des événements seront transmis à notre widget.
Comme QWidget ne définit pas de gestionnaire d'événements spécifique pour les gestes, le widget doit réimplémenter la fonction générale QWidget::event() pour recevoir les événements liés aux gestes.
bool ImageWidget::event(QEvent *event) { if (event->type() == QEvent::Gesture) return gestureEvent(static_cast<QGestureEvent*>(event)); return QWidget::event(event); }
Nous implémentons le gestionnaire d'événements pour déléguer les événements gestuels à une fonction privée spécifiquement écrite pour cette tâche, et transmettre tous les autres événements à l'implémentation de QWidget.
La fonction gestureHandler() examine les gestes fournis par la nouvelle version de QGestureEvent. Étant donné qu'un seul geste d'un type donné peut être utilisé sur un widget à un moment donné, nous pouvons vérifier chaque type de geste à l'aide de la fonction QGestureEvent::gesture() :
bool ImageWidget::gestureEvent(QGestureEvent *event) { qCDebug(lcExample) << "gestureEvent():" << event; if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) swipeTriggered(static_cast<QSwipeGesture *>(swipe)); else if (QGesture *pan = event->gesture(Qt::PanGesture)) panTriggered(static_cast<QPanGesture *>(pan)); if (QGesture *pinch = event->gesture(Qt::PinchGesture)) pinchTriggered(static_cast<QPinchGesture *>(pinch)); return true; }
Si un objet QGesture est fourni pour un certain type de geste, nous appelons une fonction spéciale pour le traiter, en coulant l'objet gesture dans la sous-classe QGesture appropriée.
Pour illustrer la manière dont un geste standard peut être interprété par une application, nous montrons l'implémentation de la fonction pinchTriggered(), qui gère le geste de pincement lorsque l'utilisateur déplace deux doigts sur l'écran ou le périphérique d'entrée :
void ImageWidget::pinchTriggered(QPinchGesture *gesture) { QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); if (changeFlags & QPinchGesture::RotationAngleChanged) { qreal rotationDelta = gesture->rotationAngle() - gesture->lastRotationAngle(); rotationAngle += rotationDelta; qCDebug(lcExample) << "pinchTriggered(): rotate by" << rotationDelta << "->" << rotationAngle; } if (changeFlags & QPinchGesture::ScaleFactorChanged) { currentStepScaleFactor = gesture->totalScaleFactor(); qCDebug(lcExample) << "pinchTriggered(): zoom by" << gesture->scaleFactor() << "->" << currentStepScaleFactor; } if (gesture->state() == Qt::GestureFinished) { scaleFactor *= currentStepScaleFactor; currentStepScaleFactor = 1; } update(); }
La classe QPinchGesture fournit des propriétés permettant d'interpréter le changement de distance entre les deux points de contact comme un facteur de zoom, et l'angle delta comme une rotation à appliquer à l'image. Le point central entre les deux points de contact pourrait être utilisé pour faire glisser l'image, mais dans cet exemple, nous utilisons le geste panoramique à cette fin.
La valeur scaleFactor() est une valeur relative représentant l'ampleur de la variation du zoom d'un événement à l'autre, tandis que la valeur totalScaleFactor() indique l'ampleur du zoom exprimée depuis le début du geste. Lorsque les points de contact sont relâchés et qu'un autre geste commence, totalScaleFactor() recommence à 1,0. Dans ce cas, nous stockons totalScaleFactor() dans la variable currentStepScaleFactor afin qu'elle puisse être utilisée dans paintEvent() pour mettre l'image à l'échelle. Il serait également possible de multiplier simplement le facteur d'échelle total stocké par scaleFactor() dans le gestionnaire de pincement.
En revanche, rotationAngle() représente la rotation depuis le début du geste de pincement, tandis que lastRotationAngle() fournit la valeur précédente. Il est donc nécessaire de faire une soustraction pour obtenir un delta incrémental. Lorsque l'utilisateur commence un nouveau geste de pincement, rotationAngle() repart de zéro et nous voulons que l'image commence à tourner à partir de son angle actuel. Pour ce faire, nous ajoutons le delta à la valeur stockée rotationAngle (qui sera appliquée à paintEvent()). Si nous nous contentions d'affecter totalRotationAngle() à la valeur stockée rotationAngle, un nouveau geste entraînerait la réinitialisation de l'image à l'endroit avant qu'elle ne commence à tourner à nouveau. Mais il serait possible de stocker l'angle de rotation depuis le début du geste et de l'ajouter à rotationAngle dans paintEvent(), de la même manière que nous stockons l'amplitude du zoom depuis le début du geste.
Les gestes de panoramique et de balayage de cet exemple sont également gérés dans des fonctions distinctes et utilisent les valeurs des propriétés des objets QGesture qui leur sont transmises.
void ImageWidget::paintEvent(QPaintEvent*) { QPainter p(this); if (files.isEmpty() && !path.isEmpty()) { p.drawText(rect(), Qt::AlignCenter|Qt::TextWordWrap, tr("No supported image formats found")); return; } const qreal iw = currentImage.width(); const qreal ih = currentImage.height(); const qreal wh = height(); const qreal ww = width(); p.translate(ww / 2, wh / 2); p.translate(horizontalOffset, verticalOffset); p.rotate(rotationAngle); p.scale(currentStepScaleFactor * scaleFactor, currentStepScaleFactor * scaleFactor); p.translate(-iw / 2, -ih / 2); p.drawImage(0, 0, currentImage); }
Dans paintEvent(), scaleFactor représente le niveau de zoom avant le début du geste de pincement, tandis que currentStepScaleFactor représente le facteur de zoom supplémentaire pendant qu'un geste de pincement est en cours. En ce qui concerne la rotation, seul l'angle de rotation actuel est stocké. Les décalages horizontaux et verticaux représentent la distance à laquelle l'image a été déplacée par le geste de panoramique.
© 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.