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.