Pregunta

Esto me ha estado molestando desde hace más de dos días, así que pensé que debería preguntar. Estoy usando Qt 4.5.3 (compilado con VC2008) en Win7.

Tengo MyGraphicsView (hereda QGraphicsView) y myFilter (hereda QObject) clases.

Cuando instalo el objeto myFilter como un filtro de eventos a MyGraphicsView, eventos del ratón se entregan a myFilter después que se entregan a MyGraphicsView mientras que los eventos clave son entregados a myFilter antes que se entregan a MyGraphicsView.

En el segundo caso, se instala el objeto myFilter como un filtro de eventos a MyGraphicsView-> ventana gráfica () (que es un QGLWidget standart), eventos del ratón se entregan a myFilter antes que se entregan a MyGraphicsView, mientras que los eventos clave son entregados a solamente MyGraphicsView.

Se supone que los eventos que se entregarán a los filtros de sucesos antes de ser entregados al objeto real, ¿por qué sucede esto? ¿Qué debo hacer para asegurar este orden?

Gracias de antemano. Atentamente.

¿Fue útil?

Solución

QGraphicsView es una subclase de QAbstractScrollArea que es la causa de estos comportamientos.

En el primer caso, la QAbstractScrollArea añade a sí mismo como un filtro de evento a la MyGraphicsView cuando se llama SetViewport (). filtro de eventos de la QAbstractScrollArea captura el evento de ratón, primero envía a través viewportEvent (), y luego a la gestión de eventos QWidget que se propaga a los controladores de eventos MyGraphicsView ratón. Sólo después de esto haya terminado filtro de eventos de la QAbstractScrollArea y myFilter pone a funcionar.

En el segundo caso, los eventos clave se entregan sólo a la MyGraphicsView porque en SetViewport () la QAbstractScrollArea se fija como el proxy de enfoque. Si el proxy enfoque se restablece con el siguiente código, se entregarán los eventos clave.

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

Una alternativa es instalar el filtro de eventos tanto en la vista gráfica y su ventana, pero modificar el filtro para eventos clave única de proceso de eventos de un objeto y de ratón de la otra.

Cambiar MyFilter.h

  QObject *keyObj;
  QObject *mouseObj;

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

Cambiar MyFilter.cpp

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

y

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

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

Otros consejos

¿Qué hay que tratar de no usar filtro, pero reimplementar manipuladores QEvent necesarias en MyGraphicsView como aquí:

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);
}
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top