이 페이지에서

위젯 및 그래픽 뷰에서의 제스처

Qt에는 사용되는 입력 방식과 무관하게 일련의 이벤트를 통해 제스처를 구성할 수 있는 제스처 프로그래밍 프레임워크가 포함되어 있습니다. 제스처는 마우스의 특정 움직임, 터치스크린 동작, 또는 다른 소스에서 발생하는 일련의 이벤트일 수 있습니다. 입력의 특성, 제스처의 해석 및 수행되는 동작은 개발자가 결정합니다.

개요

QGesture QGesture 는 Qt 제스처 프레임워크의 핵심 클래스로, 사용자가 수행한 제스처에 대한 정보를 담는 컨테이너 역할을 합니다. 는 모든 제스처에 공통적인 일반 정보를 제공하는 속성을 노출하며, 이러한 속성을 확장하여 제스처별 추가 정보를 제공할 수 있습니다. 일반적인 패닝, 핀칭 및 스와이프 제스처는 각각 , , 와 같은 특수화된 클래스로 표현됩니다. QPanGesture QPinchGesture QSwipeGesture

개발자는 ` QGestureRecognizer ` 클래스를 상속하고 확장하여 새로운 제스처를 구현할 수도 있습니다. 새로운 제스처에 대한 지원을 추가하려면 입력 이벤트에서 해당 제스처를 인식하는 코드를 구현해야 합니다. 이에 대한 내용은 ‘나만의 제스처 인식기 만들기’ 섹션에서 설명합니다.

위젯에서 표준 제스처 사용하기

제스처는 ` QWidget ` 및 ` QGraphicsObject ` 하위 클래스의 인스턴스에 대해 활성화할 수 있습니다. 제스처 입력을 수신하는 객체는 이 문서 전체에서 ‘대상 객체’라고 지칭됩니다.

대상 객체에 제스처를 활성화하려면, 필요한 제스처 유형을 설명하는 인자를 전달하여 해당 객체의 QWidget::grabGesture() 또는 QGraphicsObject::grabGesture() 함수를 호출하십시오. 표준 유형은 Qt::GestureType 열거형으로 정의되며, 널리 사용되는 다양한 제스처가 포함되어 있습니다.

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

위의 코드에서는 대상 객체 자체의 생성자에서 제스처가 설정됩니다.

이벤트 처리

사용자가 제스처를 수행하면 QGestureEvent 이벤트가 대상 객체로 전달되며, 위젯의 경우 QWidget::event() 핸들러 함수를, 그래픽 객체의 경우 QGraphicsItem::sceneEvent() 함수를 재구현하여 이를 처리할 수 있습니다.

하나의 대상 객체가 하나 이상의 제스처 유형을 구독할 수 있으므로, ` QGestureEvent `는 하나 이상의 ` QGesture`를 포함할 수 있으며, 이는 여러 가지 가능한 제스처가 동시에 활성 상태임을 나타냅니다. 이 경우, 해당 여러 제스처를 어떻게 처리할지 결정하고, 일부 제스처를 다른 제스처에 우선하여 취소할지 여부를 선택하는 것은 위젯의 몫입니다.

QGesture QGestureEvent 객체 내에 포함된 각 는 개별적으로 또는 모두 함께 accepted() 또는 ignored() 처리될 수 있습니다. 또한, 여러 게터(getter)를 사용하여 개별 데이터 객체(상태)를 조회할 수 있습니다. QGesture

이벤트 처리를 위한 표준 절차

QGesture 는 위젯에 도착하면 기본적으로 수락됩니다. 하지만 제스처를 항상 명시적으로 수락하거나 거부하는 것이 좋은 관행입니다. 일반적인 규칙은, 제스처를 수락하면 이를 사용한다는 의미이며, 무시하면 이에 관심이 없다는 의미입니다. 제스처를 무시하면 다른 대상 객체에 전달되거나 취소될 수 있습니다.

각 제스처( QGesture )는 여러 상태를 거치며, 상태를 변경하는 데에는 명확하게 정의된 방식이 있습니다. 일반적으로 사용자 입력(예: 상호작용 시작 및 중지)이 상태 변경의 원인이 되지만, 위젯 자체도 상태 변경을 유발할 수 있습니다.

특정 QGesture 가 위젯이나 그래픽 항목에 처음 전달될 때는 Qt::GestureStarted 상태에 있습니다. 이 시점에서 제스처를 처리하는 방식에 따라 나중에 해당 제스처와 상호작용할 수 있는지 여부가 결정됩니다.

  • 제스처를 수락한다는 것은 위젯이 해당 제스처에 반응함을 의미하며, 그 후 Qt::GestureUpdated 상태의 제스처가 이어집니다.
  • 제스처를 무시하면 해당 제스처가 다시는 제공되지 않습니다. 또한 해당 제스처는 상위 위젯이나 항목에도 제공됩니다.
  • 제스처가 시작 상태에 있고 수락된 상태에서 setGestureCancelPolicy()를 호출하면 다른 제스처가 취소될 수 있습니다.

QGesture::CancelAllInContext 를 사용하여 제스처를 취소하면, 명시적으로 수락되지 않은 한 모든 상태의 제스처가 취소됩니다. 이는 자식 위젯의 활성 제스처가 취소된다는 것을 의미합니다. 또한 위젯이 제스처를 무시할 경우, 동일한 QGestureEvent 에서 전달된 제스처도 취소된다는 것을 의미합니다. 이는 관심 있는 제스처를 제외한 모든 제스처를 걸러내는 데 유용한 방법일 수 있습니다.

이벤트 처리 예제

편의를 위해 ‘Image Gestures Example’은 일반적인 ` event()` 핸들러 함수를 재구현하고, 제스처 이벤트를 특화된 `gestureEvent()` 함수로 위임합니다:

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

대상 객체로 전달된 제스처 이벤트는 개별적으로 검토하여 적절하게 처리할 수 있습니다:

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

제스처에 대응하는 것은 단순히 대상 객체로 전송된 ` QGestureEvent `에 포함된 ` QGesture ` 객체를 확보하고, 그 안에 담긴 정보를 확인하는 과정입니다.

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

여기서는 사용자가 위젯을 스와이프한 방향을 확인하고 그에 따라 위젯의 내용을 수정합니다.

나만의 제스처 인식기 만들기

새로운 제스처에 대한 지원을 추가하려면 새로운 제스처 인식기를 생성하고 등록해야 합니다. 제스처 인식 과정에 따라 새로운 제스처 객체를 생성해야 할 수도 있습니다.

새로운 인식기를 생성하려면 ` QGestureRecognizer `을 상속받아 사용자 정의 인식기 클래스를 만들어야 합니다. 반드시 재구현해야 하는 가상 함수가 하나 있고, 필요에 따라 재구현할 수 있는 함수가 두 개 더 있습니다.

입력 이벤트 필터링

recognize() 함수는 반드시 재구현해야 합니다. 이 함수는 대상 객체에 대한 수신 입력 이벤트를 처리하고 필터링하며, 해당 이벤트가 인식기가 찾고 있는 제스처에 해당하는지 여부를 판단합니다.

이 함수 내에서 제스처 인식 로직이 구현되며( Qt::GestureState 열거형을 기반으로 한 상태 머신을 사용할 수도 있음), 제공된 QGesture 객체에 인식 프로세스의 상태에 대한 영구 정보를 저장할 수 있습니다.

recognize() 함수는 주어진 제스처와 대상 객체에 대한 인식 상태를 나타내는 QGestureRecognizer::Result 값을 반환해야 합니다. 이를 통해 제스처 이벤트가 대상 객체에 전달될지 여부가 결정됩니다.

사용자 정의 제스처

사용자 정의 QGesture 서브클래스를 사용하여 제스처를 표현하기로 선택한 경우, 표준 QGesture 인스턴스 대신 해당 제스처 클래스의 인스턴스를 생성하도록 create() 함수를 재구현해야 합니다. 또는 표준 QGesture 인스턴스를 사용하되, 처리하려는 제스처의 구체적인 세부 사항을 표현하기 위해 추가적인 동적 속성을 부여할 수도 있습니다.

제스처 재설정

제스처가 취소될 때 재설정되거나 별도로 특별하게 처리되어야 하는 사용자 정의 제스처 객체를 사용하는 경우, 이러한 특수 작업을 수행하기 위해 reset() 함수를 재구현해야 합니다.

QGesture 객체는 대상 객체와 제스처 유형의 각 조합에 대해 한 번만 생성되며, 사용자가 대상 객체에서 동일한 유형의 제스처를 수행하려고 시도할 때마다 재사용될 수 있습니다. 따라서 reset() 함수를 재구현하여 이전 제스처 인식 시도 후 잔여 데이터를 정리하는 것이 유용할 수 있습니다.

새로운 제스처 인식기 사용하기

제스처 인식기를 사용하려면 ` QGestureRecognizer ` 서브클래스의 인스턴스를 생성하고, ` QGestureRecognizer::registerRecognizer()`를 통해 애플리케이션에 등록해야 합니다. 특정 유형의 제스처에 대한 인식기는 ` QGestureRecognizer::unregisterRecognizer()`를 사용하여 제거할 수 있습니다.

추가 자료

'이미지 제스처 예제'에서는 간단한 이미지 뷰어 애플리케이션에서 위젯에 제스처를 활성화하는 방법을 보여줍니다.

의 제스처 Qt Quick

Qt Quick 에는 범용적인 전역 제스처 인식기가 없으며, 대신 개별 컴포넌트가 각자의 방식으로 터치 이벤트에 반응할 수 있습니다. 예를 들어, ` PinchArea `는 두 손가락 제스처를 처리하고, ` Flickable `는 한 손가락으로 콘텐츠를 휙 넘기는 동작을 처리하며, ` MultiPointTouchArea `는 임의의 수의 터치 지점을 처리할 수 있고 애플리케이션 개발자가 사용자 정의 제스처 인식 코드를 작성할 수 있게 해줍니다.

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