QGraphicsView и eventFilter - PullRequest
       14

QGraphicsView и eventFilter

11 голосов
/ 15 марта 2010

Это беспокоило меня больше двух дней, поэтому я подумал, что должен спросить. Я использую Qt 4.5.3 (скомпилировано с VC2008) на Win7.

У меня есть классы MyGraphicsView (наследует QGraphicsView) и MyFilter (наследует QObject).

Когда я устанавливаю объект MyFilter в качестве фильтра событий в MyGraphicsView, события мыши доставляются в MyFilter после , они доставляются в MyGraphicsView, тогда как события Key доставляются в MyFilter до . доставлено в MyGraphicsView.

Во втором случае я устанавливаю объект MyFilter в качестве фильтра событий в MyGraphicsView-> viewport () (который является стандартным QGLWidget), события мыши доставляются в MyFilter до того, как доставляются в MyGraphicsView. тогда как ключевые события доставляются только в MyGraphicsView.

Предполагается, что события доставляются в фильтры событий до того, как они доставляются к реальному объекту, так почему же это происходит? Что я должен сделать, чтобы обеспечить этот заказ?

Заранее спасибо. С уважением.

Ответы [ 2 ]

12 голосов
/ 23 марта 2010

QGraphicsView является подклассом QAbstractScrollArea, который является причиной такого поведения.

В первом случае QAbstractScrollArea добавляет себя в качестве фильтра событий в MyGraphicsView при вызове setViewport (). Фильтр событий 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);
0 голосов
/ 19 марта 2010

Как насчёт попробовать не использовать фильтр, а переопределить необходимые обработчики QEvent в MyGraphicsView, как здесь:

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