QGraphicsView和eventFilter

时间:2010-03-15 09:12:53

标签: qt events qt4 qgraphicsview

这已经困扰了我两天多,所以我想我应该问。我在Win7上使用Qt 4.5.3(用VC2008编译)。

我有MyGraphicsView(继承QGraphicsView)和MyFilter(继承QObject)类。

当我将MyFilter对象作为事件过滤器安装到MyGraphicsView时,鼠标事件在传递到MyGraphicsView之后传递给MyFilter ,而Key事件在之前传递给MyFilter 它们被发送到MyGraphicsView。

在第二种情况下,我将MyFilter对象作为事件过滤器安装到MyGraphicsView-> viewport()(这是一个标准的QGLWidget),鼠标事件在传递之前传递给MyFilter 到MyGraphicsView,而Key事件只传递给 MyGraphicsView。

事件应该在传递给实际对象之前传递给事件过滤器,为什么会发生这种情况?我该怎么做才能确保这个订单?

提前致谢。 最好的祝福。

2 个答案:

答案 0 :(得分:12)

QGraphicsView是QAbstractScrollArea的子类,它是导致这些行为的原因。

在第一种情况下,当调用setViewport()时,QAbstractScrollArea将自身添加为MyGraphicsView的事件过滤器。 QAbstractScrollArea的事件过滤器捕获鼠标事件,首先通过viewportEvent()发送它,然后传递给传播到MyGraphicsView鼠标事件处理程序的QWidget事件处理。只有在此之后才完成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);

答案 1 :(得分:-2)

如何尝试不使用过滤器,但在MyGraphicsView重新实现必要的QEvent处理程序,如下所示:

void MyGraphicsView::mousePressEvent(QMouseEvent* pe)
{
if (pe->buttons() & Qt::LeftButton)
{
    this->setCursor(Qt::CrossCursor);
    zoomOrigin = pe->pos();
    rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    rubberBand->setGeometry(QRect(zoomOrigin, QSize(0,0)));
    rubberBand->show();
}
if (pe->buttons() & Qt::MidButton)
{
    panOrigin = pe->pos();
        this->setCursor(Qt::ClosedHandCursor);
}
}