11

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

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

当我将 MyFilter 对象作为事件过滤器安装到 MyGraphicsView 时,鼠标事件在传递到 MyGraphicsView传递到 MyFilter,而键事件在传递到 MyGraphicsView之前传递到 MyFilter。

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

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

提前致谢。最好的祝福。

4

2 回答 2

13

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);
于 2010-03-23T16:01:56.693 回答
-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);
}
}
于 2010-03-19T08:19:38.880 回答