QGraphicsView и eventFilter

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

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

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

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

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

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

11
задан erelender 15 March 2010 в 09:12
поделиться

2 ответа

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

В первом случае QAbstractScrollArea добавляет себя в качестве фильтра событий в MyGraphicsView при вызове setViewport(). Фильтр событий QAbstractScrollArea перехватывает событие мыши, сначала посылает его через viewportEvent(), а затем в обработку событий QWidget, которая распространяется на обработчики событий мыши MyGraphicsView. Только после этого фильтр событий QAbstractScrollArea завершается и запускается MyFilter.

Во втором случае ключевые события доставляются только в MyGraphicsView, потому что в setViewport() QAbstractScrollArea устанавливает себя в качестве прокси фокуса. Если прокси фокуса сбросить с помощью следующего кода, то ключевые события будут доставлены.

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

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

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);
13
ответ дан 3 December 2019 в 09:40
поделиться

Как насчет того, чтобы попробовать не использовать filter, а переделать необходимые обработчики 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);
}
}
-2
ответ дан 3 December 2019 в 09:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: