QGraphicsView 是 QAbstractScrollArea 的子类,它是这些行为的原因。
在第一种情况下,当调用 setViewport() 时,QAbstractScrollArea 将自身作为事件过滤器添加到 MyGraphicsView。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);