Manipulando Eventos de Mouse no Qt com Event Filters

No Qt, o fluxo de uma aplicação é conduzido por um ciclo de eventos iniciado pela chamada ao método QApplication::exec(). Quando um evento, como um clique ou movimento do mouse, ocorre, o Qt cria um objeto derivado de QEvent e o entrega ao método event() do componente alvo. Este método atua como um distribuidor, direcionando o evento para o manipulador específico correspondente, como mousePressEvent().

Um mecanismo mais avançado para interceptação e processamento de eventos é o Event Filter. Um objeto pode instalar um filtro em outro objeto para inspecionar e potencialmente consumir eventos antes que eles atinjam os manipuladores padrão do alvo. Isso é feito sobrescrevendo o método eventFilter(QObject *watched, QEvent *event).

Interceptando Eventos de Mouse com um Filtro

O exemplo a seguir demonstra como usar um event filter para capturar eventos de movimento do mouse sobre um QLabel, exibindo as coordenadas do cursor.

Primeiro, declaramos a classe do widget principal (MainWindow) que irá conter o filtro.

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:
    // Declaração do filtro de eventos
    bool eventFilter(QObject *target, QEvent *occurrence) override;

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

Na implementação, configuramos o filtro no construtor. O método installEventFilter() é chamado no objeto que será monitorado, no caso, um QLabel chamado coordLabel. A propriedade setMouseTracking(true) é ativada para que eventos de movimento sejam gerados mesmo sem um botão pressionado.

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent>
#include <QEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // Instala o filtro de eventos no QLabel
    ui->coordLabel->installEventFilter(this);
    // Habilita o rastreamento contínuo do mouse
    ui->coordLabel->setMouseTracking(true);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::eventFilter(QObject *target, QEvent *occurrence)
{
    // Verifica se o evento ocorreu no label correto
    if (target == ui->coordLabel) {
        // Verifica se o evento é de movimento do mouse
        if (occurrence->type() == QEvent::MouseMove) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(occurrence);
            // Formata e exibe as coordenadas no próprio label
            QString info = QString("Posição do Mouse: X=%1, Y=%2")
                               .arg(mouseEvent->pos().x())
                               .arg(mouseEvent->pos().y());
            ui->coordLabel->setText(info);
            // Retorna true para indicar que o evento foi tratado e não deve ser propagado
            return true;
        }
    }
    // Para outros eventos ou objetos, repassa para o processamento padrão
    return QMainWindow::eventFilter(target, occurrence);
}

Funcionamento do Filtro de Eventos

No método eventFilter:
1. O parâmetro target identifica qual objeto originou o evento.
2. O parâmetro occurrence contém os detalhes do evento.
3. A lógica verifica se o target é o label desejado e se o tipo do evento é QEvent::MouseMove.
4. Se verdadeiro, o evento é convertido para QMouseEvent, as coordenadas são extraídas e exibidas.
5. Retornra true sinaliza que o evento foi totalmente processado pelo filtro, impedindo seu encaminhamento para os manipuladores de evento padrão do label (como mouseMoveEvent()).
6. Caso contrário, retornar o resultado da implementação da classe base (QMainWindow::eventFilter) permite que o fluxo normal de eventos continue.

Este mecanismo é particularmente útil para cenários onde é necessário monitorar ou modificar o comportamento de eventos em componentes dos quais não se é o proprietário direto, centralizando a lógica de interceptação.

Tags: Qt EventFilter QEvent MouseEvent QMouseEvent

Publicado em 9-9 21:43