Gestos en Widgets y Vista Gráfica
Qt incluye un framework para la programación de gestos que tiene la capacidad de formar gestos a partir de una serie de eventos, independientemente de los métodos de entrada utilizados. Un gesto puede ser un movimiento particular del ratón, una acción de la pantalla táctil, o una serie de eventos de alguna otra fuente. La naturaleza de la entrada, la interpretación del gesto y la acción realizada son elección del desarrollador.
Visión general
QGesture es la clase central en el marco de gestos de Qt, que proporciona un contenedor para la información sobre los gestos realizados por el usuario. QGesture expone propiedades que proporcionan información general que es común a todos los gestos, y éstas se pueden ampliar para proporcionar información adicional específica del gesto. Los gestos comunes de desplazamiento, pellizco y barrido están representados por clases especializadas: QPanGesture QPinchGesture y QSwipeGesture.
Los desarrolladores también pueden implementar nuevos gestos subclasificando y ampliando la clase QGestureRecognizer. Añadir soporte para un nuevo gesto implica implementar código para reconocer el gesto a partir de eventos de entrada. Esto se describe en la sección Crear su propio reconocedor de gestos.
Uso de gestos estándar con widgets
Los gestos pueden activarse para instancias de las subclases QWidget y QGraphicsObject. Un objeto que acepta la entrada de gestos se denomina objeto de destino en toda la documentación.
Para activar un gesto para un objeto de destino, llame a su función QWidget::grabGesture() o QGraphicsObject::grabGesture() con un argumento que describa el tipo de gesto requerido. Los tipos estándar están definidos por el enum Qt::GestureType e incluyen muchos gestos de uso común.
for (Qt::GestureType gesture : gestures) grabGesture(gesture);
En el código anterior, los gestos se configuran en el constructor del propio objeto de destino.
Manejo de eventos
Cuando el usuario realiza un gesto, se enviarán eventos QGestureEvent al objeto de destino, que pueden gestionarse reimplementando la función de gestión QWidget::event() para widgets o QGraphicsItem::sceneEvent() para objetos gráficos.
Dado que un objeto de destino puede suscribirse a más de un tipo de gesto, QGestureEvent puede contener más de un QGesture, lo que indica que varios gestos posibles están activos al mismo tiempo. Corresponde entonces al widget determinar cómo manejar esos gestos múltiples y elegir si algunos deben cancelarse en favor de otros.
Cada QGesture contenido dentro de un objeto QGestureEvent puede ser aceptado() o ignorado() individualmente, o todos juntos. Además, se pueden consultar los objetos de datos QGesture individuales (el estado) utilizando varios getters.
Procedimiento estándar para la gestión de eventos
Un QGesture es aceptado por defecto cuando llega a tu widget. Sin embargo, es una buena práctica aceptar o rechazar siempre explícitamente un gesto. La regla general es que, si aceptas un gesto, lo estás utilizando. Si lo ignoras, es que no te interesa. Ignorar un gesto puede significar que se ofrezca a otro objeto objetivo o que se cancele.
Cada QGesture tiene varios estados por los que pasa; hay una forma bien definida de cambiar el estado, normalmente la entrada del usuario es la causa de los cambios de estado (iniciando y deteniendo la interacción, por ejemplo) pero el widget también puede causar cambios de estado.
La primera vez que un widget o elemento gráfico recibe un determinado QGesture, se encontrará en el estado Qt::GestureStarted. La forma en que se maneja el gesto en este momento influye en si se puede interactuar con él más adelante.
- Aceptar el gesto significa que el widget actúa sobre el gesto y que seguirán gestos con el estado Qt::GestureUpdatedstate.
- Ignorar el gesto significa que no se te volverá a ofrecer. También se ofrecerá a un widget o ítem padre.
- Llamar a setGestureCancelPolicy() en el gesto cuando está en su estado inicial, y también es aceptado puede causar que otros gestos sean cancelados.
Si se utiliza QGesture::CancelAllInContext para cancelar un gesto, se cancelarán todos los gestos, en cualquier estado, a menos que se acepten explícitamente. Esto significa que los gestos activos en los niños se cancelarán. También significa que los gestos enviados en el mismo QGestureEvent se cancelarán si el widget los ignora. Esta puede ser una forma útil de filtrar todos los gestos excepto el que te interesa.
Ejemplo de gestión de eventos
Por conveniencia, el ejemplo de gestos de imagen reimplementa la función general event() y delega los eventos de gestos a una función especializada gestureEvent():
bool ImageWidget::event(QEvent *event) { if (event->type() == QEvent::Gesture) return gestureEvent(static_cast<QGestureEvent*>(event)); return QWidget::event(event); }
Los eventos de gestos entregados al objeto de destino pueden ser examinados individualmente y tratados apropiadamente:
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; }
Responder a un gesto es simplemente una cuestión de obtener el objeto QGesture entregado en el QGestureEvent enviado al objeto de destino y examinar la información que contiene.
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(); } }
En este caso, examinamos la dirección en la que el usuario ha deslizado el widget y modificamos su contenido en consecuencia.
Creación de un reconocedor de gestos propio
Añadir soporte para un nuevo gesto implica crear y registrar un nuevo reconocedor de gestos. Dependiendo del proceso de reconocimiento del gesto, también puede implicar la creación de un nuevo objeto de gesto.
Para crear un nuevo reconocedor, es necesario subclasificar QGestureRecognizer para crear una clase de reconocedor personalizada. Hay una función virtual que debe reimplementar y otras dos que pueden reimplementarse según sea necesario.
Filtrado de eventos de entrada
La función recognize() debe ser reimplementada. Esta función maneja y filtra los eventos de entrada entrantes para los objetos de destino y determina si corresponden o no al gesto que el reconocedor está buscando.
Aunque la lógica para el reconocimiento de gestos se implementa en esta función, posiblemente utilizando una máquina de estados basada en los enums Qt::GestureState, puede almacenar información persistente sobre el estado del proceso de reconocimiento en el objeto QGesture suministrado.
Su función recognize() debe devolver un valor de QGestureRecognizer::Result que indique el estado del reconocimiento para un gesto y un objeto de destino dados. Esto determina si se enviará o no un evento de gesto a un objeto de destino.
Gestos personalizados
Si decide representar un gesto mediante una subclase personalizada de QGesture, deberá reimplementar la función create() para construir instancias de su clase de gesto en lugar de instancias estándar de QGesture. Otra posibilidad es utilizar instancias estándar de QGesture, pero añadirles propiedades dinámicas adicionales para expresar detalles específicos del gesto que se desea manejar.
Restablecer gestos
Si utiliza objetos de gesto personalizados que deben restablecerse o gestionarse de forma especial cuando se cancela un gesto, deberá reimplementar la función reset() para realizar estas tareas especiales.
Tenga en cuenta que los objetos QGesture sólo se crean una vez para cada combinación de objeto de destino y tipo de gesto, y podrían reutilizarse cada vez que el usuario intente realizar el mismo tipo de gesto en el objeto de destino. Como resultado, puede ser útil reimplementar la función reset() para limpiar después de cada intento anterior de reconocer un gesto.
Uso de un nuevo reconocedor de gestos
Para utilizar un reconocedor de gestos, construya una instancia de su subclase QGestureRecognizer y regístrela en la aplicación con QGestureRecognizer::registerRecognizer(). Un reconocedor para un determinado tipo de gesto puede eliminarse con QGestureRecognizer::unregisterRecognizer().
Lecturas adicionales
El ejemplo de gestos de imagen muestra cómo habilitar gestos para un widget en una aplicación sencilla de visor de imágenes.
Gestos en Qt Quick
Qt Quick no tiene un reconocedor de gestos global genérico, sino que los componentes individuales pueden responder a los eventos táctiles a su manera. Por ejemplo, PinchArea gestiona gestos con dos dedos, Flickable es para desplazar contenido con un solo dedo y MultiPointTouchArea puede gestionar un número arbitrario de puntos táctiles y permitir al desarrollador de la aplicación escribir código de reconocimiento de gestos personalizado.
© 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.