2010-03-15 7 views
11

이것은 지금 2 일 이상 나를 괴롭 히고 있습니다. 그래서 물어봐야 할 것 같았습니다. Win7에서 Qt 4.5.3 (VC2008로 컴파일)을 사용하고 있습니다.QGraphicsView 및 eventFilter

저는 MyGraphicsView (QGraphicsView 상속) 및 MyFilter (QObject 상속) 클래스를 보유하고 있습니다.

내가 MyGraphicsView에 이벤트 필터로 MyFilter 객체를 설치

는, 마우스 이벤트는 중요한 사건들이 MyGraphicsView에게 전달 전에 MyFilter 에 전달되는 반면, 그들은 MyGraphicsView에게 전달 후 MyFilter 전달됩니다.

번째 경우 나 이벤트 MyGraphicsView-에 필터> 뷰포트() (a의 standart QGLWidget 임)로 MyFilter 개체 설치 마우스 이벤트는 그들이 MyGraphicsView 전달된다 전에 MyFilter 로 전달되는 중요한 반면되고 이벤트는 에만 MyGraphicsView로 전달됩니다.

이벤트는 실제 객체에 전달되기 전에 이벤트 필터로 전달되어야한다고 생각됩니다. 그렇다면 왜 이런 일이 발생합니까? 이 명령서를 지키려면 어떻게해야합니까?

미리 감사드립니다. 최고 감사합니다.

어떻게 여기처럼 MyGraphicsView에서 필터를 사용하지 않으려 고하지만 필요한 QEvent 처리기를 재 구현하려고
+1

ordet가 문제로 보이므로 코드 조각이 유용 할 수 있습니다. – gregseth

+0

OK 얘들 아, 여기에 문제를 재현하는 최소한의 코드에 대한 링크가 있습니다. http://rapidshare.com/files/363574158/QGVEF.rar – erelender

답변

12

를 QGraphicsView이 이러한 행동의 원인 QAbstractScrollArea의 서브 클래스입니다.

첫 번째 경우, QAbstractScrollArea는 setViewport()가 호출 될 때 MyGraphicsView에 이벤트 필터로 자신을 추가합니다. QAbstractScrollArea의 이벤트 필터는 마우스 이벤트를 캡처하여 먼저 viewportEvent()를 통해 보낸 다음 MyGraphicsView 마우스 이벤트 핸들러에 전파하는 QWidget 이벤트 처리에 보냅니다. 이 후에 만 ​​QAbstractScrollArea의 이벤트 필터가 완료되고 MyFilter가 실행됩니다.

두 번째 경우 키 이벤트는 setViewport()에서 QAbstractScrollArea 자체를 포커스 프록시로 설정하기 때문에 MyGraphicsView에만 전달됩니다. 다음 코드를 사용하여 포커스 프록시를 다시 설정하면 키 이벤트가 전달됩니다.

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

사실, 이것은 내가 지금하고있는 일이지만 해결책이라고 생각하지 않습니다. 내 이벤트 필터는 플러그인에서오고있어 객체 ​​기반 이벤트 필터링을 처리하는 것이 자신의 관심사 여야한다고 생각하지 않습니다. 그럼에도 불구하고 이것이 왜 일어나는지에 대한 설명에 감사드립니다. – erelender

+0

이전의 설명이 일반적으로 정확하다고 생각하지만, 이제 이것이 더 나은 설명이라고 생각합니다. 스크롤 영역의 주요 이벤트 처리 (페이지 위로, 페이지 아래로 등)에 신경 쓰지 않는다면 뷰포트에 이벤트 필터를 설치하고 포커스 프록시를 지우는 것이 더 간단한 해결책입니다. 그렇지 않으면 MyGraphicsView와 뷰포트에 이벤트 필터를 설치하는 것이 좋습니다. – baysmith

+0

맞습니다. 이전 솔루션이 일반적인 용도로 더 적합 할 수 있습니다. 제 경우에는 Qt & OSG와 함께 멋진 일을하려고하는데, 이것이 내 문제가 대부분 풀리지 않는 이유입니다 :). 이 솔루션은 장갑처럼 내 경우에 맞습니다. 감사합니다. 그러나 나중에 참조 할 수 있도록 다른 솔루션이 다른 사람들이 볼 수 있도록 기존 솔루션을 다른 답변으로 게시 할 수 있습니까? "편집 됨 : ... 전"링크를 통해 액세스 할 수 있습니다. – erelender

-2

:

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); 
} 
} 
+0

이미 확인했습니다. 그러나 서브 클래 싱과 이벤트 필터링은 다른 목적으로 사용되며 내 경우에는 상호 교환 할 수 없습니다. – erelender

+1

좋아요, 정말로 이벤트 필터링이 필요하다면 eventFilter() 메소드에 의해 반환 된 잘못된 true/false 값에 문제가있을 수 있습니다. 또한 http://uploading.com/files/7c7adam5/graphicsview.zip/에 테스트 프로젝트를 업로드하여 예상대로 이벤트를 처리합니다. Slackware Linux에서 현재 git 버전의 Qt로 컴파일되었습니다. 따라서이 테스트 프로젝트가 여러분의 Qt 버전 (4.5.3)에서 작동하지 않는다면 이미 해결 된 Qt의 문제 일 수는 있지만 저에게 맞는 사례는 아닙니다. 또한 그것은 플랫폼 종속 "기능"일 수 있습니다. 행운을 빕니다! –

+0

당신의 예제는 Qt 4.5.3에서도 잘 작동하기 때문에 괜찮습니다. 귀하의 예제에서, graphicsview는 QGraphicsView가 아닌 ​​QWidget을 하위 클래스로 분류합니다. 또한 이벤트 필터는 QGraphicsView가 아닌 ​​graphicsview (QWidget의 하위 클래스)에 설치되어 있으므로 문제를 재현하는 샘플 코드를 게시했습니다. 당신이 그것을 살펴 본다면, 당신은 나의 문제를 더 잘 이해할 것입니다. – erelender

관련 문제