QGraphicsView является подклассом QAbstractScrollArea, который является причиной такого поведения.
В первом случае QAbstractScrollArea добавляет себя в качестве фильтра событий в MyGraphicsView при вызове setViewport (). Фильтр событий QAbstractScrollArea захватывает событие мыши, сначала отправляет его через viewportEvent (), а затем в обработку событий QWidget, которая распространяется на обработчики событий мыши MyGraphicsView. Только после этого завершается фильтр событий QAbstractScrollArea, и MyFilter запускается.
Во втором случае ключевые события доставляются только в MyGraphicsView, потому что в setViewport () QAbstractScrollArea устанавливает себя в качестве прокси фокуса. Если фокус-прокси сбрасывается с помощью следующего кода, ключевые события будут доставлены.
w.viewport()->setFocusProxy(0);
Альтернативой является установка фильтра событий как в графическом представлении, так и в его области просмотра, но измените фильтр так, чтобы он обрабатывал только ключевые события из одного объекта и события мыши из другого.
Изменить MyFilter.h
QObject *keyObj;
QObject *mouseObj;
public:
MyFilter(QObject *keyObj, QObject *mouseObj, QObject *parent = NULL);
Изменить MyFilter.cpp
MyFilter::MyFilter(QObject *keyObj, QObject *mouseObj, QObject *parent /*= NULL*/ ) : QObject(parent), keyObj(keyObj), mouseObj(mouseObj)
и
if (obj == keyObj && e->type() == QEvent::KeyPress)
{
qDebug()<<"Key Event recieved by MyFilter";
}
else if (obj == mouseObj && e->type() == QEvent::MouseButtonPress)
{
qDebug()<<"Mouse Event recieved by MyFilter";
}
Изменить main.cpp
MyFilter *filter = new MyFilter(&w, w.viewport(), &w);
// Use this line to install to the viewport
w.viewport()->installEventFilter(filter);
//Use this line to install to MyGraphicsView
w.installEventFilter(filter);