Auf dieser Seite

Gesten in Widgets und der Grafikansicht

Qt enthält ein Framework für die Gestenprogrammierung, das in der Lage ist, Gesten aus einer Abfolge von Ereignissen zu bilden, unabhängig von den verwendeten Eingabemethoden. Eine Geste kann eine bestimmte Mausbewegung, eine Touchscreen-Aktion oder eine Abfolge von Ereignissen aus einer anderen Quelle sein. Die Art der Eingabe, die Interpretation der Geste und die ausgeführte Aktion liegen im Ermessen des Entwicklers.

Übersicht

QGesture ist die zentrale Klasse im Gesten-Framework von Qt und stellt einen Container für Informationen über vom Benutzer ausgeführte Gesten bereit. ` QGesture ` stellt Eigenschaften bereit, die allgemeine Informationen liefern, die allen Gesten gemeinsam sind, und diese können erweitert werden, um zusätzliche gestenspezifische Informationen bereitzustellen. Gängige Schwenk-, Zoom- und Wischgesten werden durch spezialisierte Klassen dargestellt: ` QPanGesture`, ` QPinchGesture ` und ` QSwipeGesture`.

Entwickler können außerdem neue Gesten implementieren, indem sie die Klasse ` QGestureRecognizer ` unterklassen und erweitern. Um Unterstützung für eine neue Geste hinzuzufügen, muss Code implementiert werden, der die Geste anhand von Eingabeereignissen erkennt. Dies wird im Abschnitt „Erstellen eines eigenen Gestenerkenners“ beschrieben.

Verwendung von Standardgesten mit Widgets

Gesten können für Instanzen von Unterklassen von „ QWidget “ und „ QGraphicsObject “ aktiviert werden. Ein Objekt, das Gesteneingaben akzeptiert, wird in der gesamten Dokumentation als Zielobjekt bezeichnet.

Um eine Geste für ein Zielobjekt zu aktivieren, rufen Sie dessen Funktion „ QWidget::grabGesture()“ oder „ QGraphicsObject::grabGesture()“ mit einem Argument auf, das den gewünschten Gestentyp angibt. Die Standardtypen sind durch die Aufzählung „ Qt::GestureType “ definiert und umfassen viele häufig verwendete Gesten.

for (Qt::GestureType gesture : gestures)
    grabGesture(gesture);

Im obigen Code werden die Gesten im Konstruktor des Zielobjekts selbst eingerichtet.

Verarbeitung von Ereignissen

Wenn der Benutzer eine Geste ausführt, werden „ QGestureEvent “-Ereignisse an das Zielobjekt übermittelt; diese können durch Neudefinition der Handler-Funktion „ QWidget::event()“ für Widgets bzw. „ QGraphicsItem::sceneEvent()“ für Grafikobjekte verarbeitet werden.

Da ein Zielobjekt mehr als einen Gestentyp abonnieren kann, kann das ` QGestureEvent ` mehr als ein ` QGesture` enthalten, was darauf hinweist, dass mehrere mögliche Gesten gleichzeitig aktiv sind. Es obliegt dann dem Widget, zu bestimmen, wie diese mehreren Gesten verarbeitet werden sollen, und zu entscheiden, ob einige zugunsten anderer abgebrochen werden sollen.

Jedes in einem „ QGestureEvent “-Objekt enthaltene „ QGesture “ kann einzeln oder alle zusammen mit „accepted()“ oder „ignored()“ behandelt werden. Zusätzlich können Sie die einzelnen „ QGesture “-Datenobjekte (den Status) mithilfe verschiedener Getter abfragen.

Standardverfahren für die Ereignisbehandlung

Eine „ QGesture “ wird standardmäßig akzeptiert, wenn sie bei Ihrem Widget eintrifft. Es empfiehlt sich jedoch, eine Geste stets explizit zu akzeptieren oder abzulehnen. Die allgemeine Regel lautet: Wenn Sie eine Geste annehmen, nutzen Sie sie. Wenn Sie sie ignorieren, haben Sie kein Interesse daran. Das Ignorieren einer Geste kann bedeuten, dass sie einem anderen Zielobjekt angeboten wird oder dass sie abgebrochen wird.

Jede „ QGesture “ durchläuft mehrere Zustände; es gibt eine genau definierte Vorgehensweise, um den Zustand zu ändern. In der Regel ist die Benutzereingabe der Auslöser für Zustandsänderungen (beispielsweise durch Starten und Beenden der Interaktion), aber auch das Widget selbst kann Zustandsänderungen bewirken.

Wenn eine bestimmte „ QGesture “ zum ersten Mal an ein Widget oder ein Grafikelement übermittelt wird, befindet sie sich im Zustand „ Qt::GestureStarted “. Die Art und Weise, wie Sie die Geste zu diesem Zeitpunkt behandeln, beeinflusst, ob Sie später mit ihr interagieren können.

  • Das Akzeptieren der Geste bedeutet, dass das Widget auf die Geste reagiert und anschließend Gesten im Zustand „Qt::GestureUpdated“ folgen.
  • Wird die Geste ignoriert, wird sie Ihnen nie wieder angeboten. Sie wird auch einem übergeordneten Widget oder Element angeboten.
  • Der Aufruf von `setGestureCancelPolicy()` für die Geste, wenn sie sich im Startzustand befindet und zudem akzeptiert wurde, kann dazu führen, dass andere Gesten abgebrochen werden.

Die Verwendung von ` QGesture::CancelAllInContext ` zum Abbrechen einer Geste führt dazu, dass alle Gesten in jedem beliebigen Zustand abgebrochen werden, sofern sie nicht explizit akzeptiert wurden. Das bedeutet, dass aktive Gesten auf untergeordneten Elementen abgebrochen werden. Es bedeutet auch, dass Gesten, die im selben ` QGestureEvent ` übermittelt wurden, abgebrochen werden, wenn das Widget sie ignoriert. Dies kann eine nützliche Methode sein, um alle Gesten außer derjenigen herauszufiltern, die für Sie von Interesse ist.

Beispiel für die Ereignisbehandlung

Der Einfachheit halber implementiert das Beispiel „Image Gestures“ die allgemeine Handler-Funktion ` event()` neu und delegiert Gestenereignisse an eine spezielle Funktion `gestureEvent()`:

bool ImageWidget::event(QEvent *event)
{
    if (event->type() == QEvent::Gesture)
        return gestureEvent(static_cast<QGestureEvent*>(event));
    return QWidget::event(event);
}

Die an das Zielobjekt übermittelten Gestenereignisse können einzeln untersucht und entsprechend verarbeitet werden:

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;
}

Um auf eine Geste zu reagieren, muss lediglich das ` QGesture `-Objekt abgerufen werden, das im an das Zielobjekt gesendeten ` QGestureEvent ` übermittelt wird, und die darin enthaltenen Informationen ausgewertet werden.

void ImageWidget::swipeTriggered(QSwipeGesture *gesture)
{
    if (gesture->state() == Qt::GestureFinished) {
        if (gesture->swipeAngle() < 45 || gesture->swipeAngle() > 225) {
            // swipe direction right or down
            qCDebug(lcExample) << "swipeTriggered(): angle"
                               << gesture->swipeAngle() << "; swipe to next";
            goNextImage();
        } else {
            // swipe direction left or up
            qCDebug(lcExample) << "swipeTriggered(): angle"
                               << gesture->swipeAngle() << "; swipe to previous";
            goPrevImage();
        }
        update();
    }
}

Hier prüfen wir die Richtung, in die der Benutzer über das Widget gewischt hat, und passen dessen Inhalt entsprechend an.

Erstellen eines eigenen Gestenerkenners

Um Unterstützung für eine neue Geste hinzuzufügen, müssen Sie einen neuen Gestenerkennungsmechanismus erstellen und registrieren. Je nach Erkennungsprozess für die Geste kann dies auch die Erstellung eines neuen Gestenobjekts erfordern.

Um einen neuen Erkenner zu erstellen, müssen Sie eine Unterklasse von ` QGestureRecognizer ` definieren, um eine benutzerdefinierte Erkennungsklasse zu erstellen. Es gibt eine virtuelle Funktion, die Sie neu implementieren müssen, sowie zwei weitere, die bei Bedarf neu implementiert werden können.

Filtern von Eingabeereignissen

Die Funktion ` recognize()` muss neu implementiert werden. Diese Funktion verarbeitet und filtert die eingehenden Eingabeereignisse für die Zielobjekte und ermittelt, ob sie der vom Erkenner gesuchten Geste entsprechen.

Obwohl die Logik für die Gestenerkennung in dieser Funktion implementiert ist – möglicherweise unter Verwendung einer Zustandsmaschine auf Basis der ` Qt::GestureState `-Enums –, können Sie dauerhafte Informationen über den Zustand des Erkennungsprozesses im bereitgestellten ` QGesture `-Objekt speichern.

Ihre Funktion ` recognize()` muss einen Wert vom Typ ` QGestureRecognizer::Result ` zurückgeben, der den Erkennungsstatus für eine bestimmte Geste und ein bestimmtes Zielobjekt angibt. Dies bestimmt, ob ein Gestenereignis an ein Zielobjekt weitergeleitet wird oder nicht.

Benutzerdefinierte Gesten

Wenn Sie eine Geste durch eine benutzerdefinierte Unterklasse von ` QGesture ` darstellen möchten, müssen Sie die Funktion ` create()` neu implementieren, um Instanzen Ihrer Gestenklasse anstelle von Standardinstanzen von ` QGesture ` zu erstellen. Alternativ können Sie auch Standardinstanzen von ` QGesture ` verwenden, diesen jedoch zusätzliche dynamische Eigenschaften hinzufügen, um spezifische Details der Geste auszudrücken, die Sie verarbeiten möchten.

Zurücksetzen von Gesten

Wenn Sie benutzerdefinierte Gestenobjekte verwenden, die zurückgesetzt oder anderweitig speziell behandelt werden müssen, wenn eine Geste abgebrochen wird, müssen Sie die Funktion ` reset()` neu implementieren, um diese speziellen Aufgaben auszuführen.

Beachten Sie, dass „ QGesture “-Objekte für jede Kombination aus Zielobjekt und Gestentyp nur einmal erstellt werden und möglicherweise jedes Mal wiederverwendet werden, wenn der Benutzer versucht, denselben Gestentyp auf dem Zielobjekt auszuführen. Daher kann es sinnvoll sein, die Funktion „ reset()“ neu zu implementieren, um nach jedem vorherigen Versuch, eine Geste zu erkennen, eine Bereinigung durchzuführen.

Verwendung eines neuen Gestenerkenners

Um einen Gestenerkenner zu verwenden, erstellen Sie eine Instanz Ihrer Unterklasse von ` QGestureRecognizer ` und registrieren Sie diese mit ` QGestureRecognizer::registerRecognizer()` in der Anwendung. Ein Erkenner für einen bestimmten Gestentyp kann mit ` QGestureRecognizer::unregisterRecognizer()` entfernt werden.

Weiterführende Informationen

Das Beispiel „Image Gestures“ zeigt, wie Gesten für ein Widget in einer einfachen Bildbetrachtungsanwendung aktiviert werden.

Gesten in Qt Quick

Qt Quick verfügt nicht über einen generischen globalen Gestenerkennungsmechanismus; vielmehr können einzelne Komponenten auf Berührungsereignisse auf ihre eigene Weise reagieren. Beispielsweise verarbeitet das ` PinchArea ` Zwei-Finger-Gesten, ` Flickable ` dient zum Wischen von Inhalten mit einem Finger und ` MultiPointTouchArea ` kann eine beliebige Anzahl von Berührungspunkten verarbeiten und ermöglicht es dem Anwendungsentwickler, benutzerdefinierten Code zur Gestenerkennung zu schreiben.

© 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.