Ответ 1
QGraphicsView является подклассом QAbstractScrollArea, который является причиной такого поведения.
В первом случае QAbstractScrollArea добавляет себя как фильтр событий в MyGraphicsView, когда вызывается setViewport(). Фильтр событий QAbstractScrollArea захватывает событие мыши, сначала отправляет его через viewportEvent(), а затем в обработку событий QWidget, которая распространяется на обработчики событий мыши MyGraphicsView. Только после этого завершается фильтрация событий QAbstractScrollArea и запускается MyFilter.
Во втором случае ключевые события доставляются только в MyGraphicsView, потому что в setViewport() QAbstractScrollArea устанавливает себя как фокус-прокси. Если прокси-сервер фокуса reset со следующим кодом, будут переданы ключевые события.
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);