QGraphicsView 和 eventFilter

发布于 2024-08-25 07:32:55 字数 516 浏览 8 评论 0原文

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

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

当我将 MyFilter 对象作为事件过滤器安装到 MyGraphicsView 时,鼠标事件传送到 MyGraphicsView 之后传送到 MyFilter,而按键事件传送到 MyFilter 之前传送到 MyFilter到我的图形视图。

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

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

提前致谢。 此致。

This has been bugging me for more than two days now, so i thought i should ask. I am using Qt 4.5.3 (compiled with VC2008) on Win7.

I have MyGraphicsView (inherits QGraphicsView) and MyFilter (inherits QObject) classes.

When i install the MyFilter object as an event filter to MyGraphicsView, Mouse events are delivered to MyFilter after they are delivered to MyGraphicsView whereas Key events are delivered to MyFilter before they are delivered to MyGraphicsView.

In the second case, i install the MyFilter object as an event filter to MyGraphicsView->viewport() (which is a standart QGLWidget), Mouse events are delivered to MyFilter before they are delivered to MyGraphicsView, whereas Key events are delivered to only MyGraphicsView.

The events are supposed to be delivered to event filters before they are delivered to the actual object, so why is this happening? What should i do to ensure this order?

Thanks in advance.
Best Regards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜未央樱花落 2024-09-01 07:32:55

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);

QGraphicsView is a subclass of QAbstractScrollArea which is the cause of these behaviors.

In the first case, the QAbstractScrollArea adds itself as a event filter to the MyGraphicsView when setViewport() is called. The QAbstractScrollArea's event filter captures the mouse event, first sends it through viewportEvent(), and then to the QWidget event handling which propagates to the MyGraphicsView mouse event handlers. Only after this is the QAbstractScrollArea's event filter finished and MyFilter gets to run.

In the second case, key events are delivered only to the MyGraphicsView because in setViewport() the QAbstractScrollArea sets itself as the focus proxy. If the focus proxy is reset with the following code, the key events will be delivered.

w.viewport()->setFocusProxy(0);

An alternative is to install the event filter on both the graphics view and its viewport, but modify the filter to only process key events from one object and mouse events from the other.

Change MyFilter.h

  QObject *keyObj;
  QObject *mouseObj;

public:
  MyFilter(QObject *keyObj, QObject *mouseObj, QObject *parent = NULL);

Change MyFilter.cpp

MyFilter::MyFilter(QObject *keyObj, QObject *mouseObj, QObject *parent /*= NULL*/ ) : QObject(parent), keyObj(keyObj), mouseObj(mouseObj)

and

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";
}

Change 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);
梦魇绽荼蘼 2024-09-01 07:32:55

如何尝试不使用过滤器,而是在 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);
}
}

How about to try not using filter but reimplement necessary QEvent handlers at MyGraphicsView like here:

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);
}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文