Sistema de Eventos en Qt Creator: Mecanismos y Manejo

En Qt, un evento es un objeto que hereda de QEvent. Los tipos comunes incluyen QKeyEvent para teclado, QMouseEvent para ratón y QTimerEvent para temporizadores. Es crucial distinguir entre eventos y señales: provienen de fuentes ditsintas y cumplen propósitos diferentes.

Enfoques para Procesar Eventos

Existen cinco estrategias principales:

  1. Sobreescribir métodos específicos del widget, como paintEvent() o mousePressEvent(). Este método solo aplica a un evento concreto de una clase específica.
  2. Reimplementar la función notify(), que ofrece control total y permite interceptar eventos antes de los filtros, pero está limitada a procesar un evento cada vez.
  3. Instalar un filtro de eventos en el objeto QApplication, lo que facilita el manejo de múltiples eventos de manera centralizada.
  4. Reimplementar la función event() de QObject, la cual intercepta eventos antes de que lleguen a los manejadores predeterminados.
  5. Instalar filtros de eventos en objetos individuales.

Propagación de Eventos

La ejecución de exec() en main() inicia el bucle de eventos de Qt. Cuando ocurre un evento, Qt construye un objeto de la subclase correspondiente de QEvent y lo dirige al QObject apropiado.

Si el widget objetivo ignora el evento, este se propaga a su widget padre. El siugiente código muestra una tecla presionada que es ignorada por una subclase personalizada de QLineEdit:

void EditorPersonalizado::keyPressEvent(QKeyEvent *eventoTecla)
{
    qDebug() << "Evento de tecla detectado en EditorPersonalizado";
    QLineEdit::keyPressEvent(eventoTecla); // Manejo base
    eventoTecla->ignore(); // Se marca como ignorado
}

El siguiente diagrama ilustra una secuencia alternativa de propagación:

  1. Filtro de eventos instalado.
  2. Método event() del widget con foco.
  3. Manejador específico del widget (ej. keyPressEvent()).
  4. Si se ignora, el manejador del widget padre.

Ejemplo de reimplementación de event():

bool EditorConFoco::event(QEvent *evento)
{
    if (evento->type() == QEvent::KeyPress)
    {
        qDebug() << "Interceptado en event() de EditorConFoco";
    }
    return QLineEdit::event(evento); // Llama al comportamiento base
}

Para instalar un filtro de eventos en un widget específico:

// En el constructor del widget contenedor:
editorObjetivo->installEventFilter(this);

// Implementación del filtro:
bool WidgetContenedor::eventFilter(QObject *objetoObservado, QEvent *evento)
{
    if (objetoObservado == editorObjetivo && evento->type() == QEvent::KeyPress)
    {
        qDebug() << "Filtro activado para editorObjetivo";
    }
    return QWidget::eventFilter(objetoObservado, evento);
}

Eventos de Ratón y Rueda

QMouseEvent proporciona datos sobre qué botón se pulsó y la posición del cursor. QWheelEvent captura el desplazamiento y dirección de la rueda del ratón.

Eventos de Teclado

QKeyEvent identifica la tecla mediante key() (ver Qt::Key en la documentación). Las teclas modificadoras (Ctrl, Shift) se obtienen con modifiers().

void WidgetPrincipal::keyPressEvent(QKeyEvent *eventoTecla)
{
    if (eventoTecla->modifiers() == Qt::ControlModifier && eventoTecla->key() == Qt::Key_P)
    {
        mostrarPanelPreferencias(); // Acción personalizada
    }
    else
    {
        QWidget::keyPressEvent(eventoTecla);
    }
}

Eventos de Temporización

QTimer emite señales periódicas. Ejemplo de un reloj digital que alterna el separador cada segundo:

// Inicialización en el constructor
temporizadorReloj = new QTimer(this);
connect(temporizadorReloj, &QTimer::timeout, this, &WidgetReloj::actualizarVisual);
temporizadorReloj->start(1000); // Intervalo de 1 segundo

// Slot privado
void WidgetReloj::actualizarVisual()
{
    QTime horaActual = QTime::currentTime();
    QString formato = horaActual.toString("hh:mm");
    if (horaActual.second() % 2 == 0)
    {
        formato[2] = ' '; // Oculta el separador alternando
    }
    pantallaLCD->display(formato);
}

Filtros de Eventos

Este mecanismo permite interceptar eventos destinados a otros objetos. Se configura mediante installEventFilter() y la reimplementación de eventFilter().

Etiquetas: Qt QEvent QKeyEvent QMouseEvent QTimerEvent

Publicado el 7-12 20:38