2017-11-23 33 views
0

QML로 작은 PoC를 프로그래밍하고 있습니다. 두 곳에서 내 코드에서 전역 마우스 위치 (예 : 장면 또는 게임 창에서 마우스 위치)에 바인드하거나 쿼리해야합니다. 마우스가 지금까지 정의한 MouseAreas 외부에있는 경우에도 마찬가지입니다.QML에서 전체 마우스 위치 쿼리

주위를 둘러 보니 전체 화면이 다른 MouseArea로 덮여있는 것처럼 보입니다. 마우스 오버가 가능할 가능성이 가장 높습니다. 그런 다음 기본 마우스 영역에 반 수동 전파 (호버) 이벤트도 처리해야합니다.

내가 여기에 뭔가를 놓친가요? 이것은 꽤 일반적인 경우처럼 보입니다 - 그것을 구현하는 더 단순하고 우아한 방법이 있습니까?

EDIT : 가장 문제가있는 경우는 MouseArea 외부로 끌고있는 것 같습니다. 아래는 V-Play 구성 요소와 derM의 마우스 이벤트 스파이를 사용하는 최소한의 예입니다. 이미지를 클릭하고 MouseArea 외부로 드래그하면 마우스 이벤트가 더 이상 나타나지 않으므로 아래 위치에 DropArea가 없으면 위치를 업데이트 할 수 없습니다.

MouseEventSpy은 답 중 하나에 대한 응답으로 here에서 가져온 것입니다. 신호에 대한 매개 변수로 위치를 포함하기 위해서만 수정됩니다.

import VPlay 2.0 
import QtQuick 2.0 
import MouseEventSpy 1.0 

GameWindow { 
    id: gameWindow 
    activeScene: scene 
    screenWidth: 960 
    screenHeight: 640 

    Scene { 
     id: scene 
     anchors.fill: parent 

     Connections { 
      target: MouseEventSpy 
      onMouseEventDetected: { 
       console.log(x) 
       console.log(y) 
      } 
     } 

     Image { 
      id: tile 
      x: 118 
      y: 190 
      width: 200 
      height: 200 
      source: "../assets/vplay-logo.png" 
      anchors.centerIn: parent 

      Drag.active: mausA.drag.active 
      Drag.dragType: Drag.Automatic 

      MouseArea { 
       id: mausA 
       anchors.fill: parent 
       drag.target: parent 
      } 
     } 
    } 
} 
+0

또한 'MouseEventSpy'의 수정 된 코드를 제공 할 수 있습니까? '... && 이벤트 -> 자연()) { QMouseEvent * 나 :;' 다음 '무효 mouseEventDetected (INT X, INT의 Y) : – derM

+1

그것은 거의 수정되지 않은, 난에 신호 프로토 타입을 변경했습니다 = (QMouseEvent *) 이벤트; emit mouseEventDetected (me-> globalX(), me-> globalY()); }' – evilkonrex

+0

'Drag.dragType'과 관련이있는 것 같습니다. 주석 처리 된 경우 작동하는 것 같습니다. 내가 해결책을 찾을 수 있는지 알게 될 것이다. – derM

답변

1

모든 마우스 이벤트가 통과하는 QGuiApplication에 eventFilter을 설치할 수 있습니다. 상기 신호를 방출 할 때

이렇게하는 방법

링크 된 용액에

here 기술되어, I는 마우스 위치에 관한 정보를 삭제. 그러나 을 eventFilter(...) -method로 전달하여 QMouseEvent으로 캐스팅하고 신호로 매개 변수로 추가하여 정보를 쉽게 검색 할 수 있습니다.

링크 된 답변에서는 QML 및 C++에서 사용할 수있는 싱글 톤으로 등록하므로 언제 어디서나 신호에 연결할 수 있습니다. 이 링크 대답에 제공되기 때문에


MouseEventSpy은 다양한 유형의 QMouseEvents을 처리합니다. 드래그를 시작하면 QMouseEvents이 아니라 QDragMoveEvents e.t.c가됩니다. 따라서 필터 메소드를 확장하여 처리해야합니다.

bool MouseEventSpy::eventFilter(QObject* watched, QEvent* event) 
{ 
    QEvent::Type t = event->type(); 
    if (t == QEvent::MouseButtonDblClick 
      || t == QEvent::MouseButtonPress 
      || t == QEvent::MouseButtonRelease 
      || t == QEvent::MouseMove) { 
     QMouseEvent* e = static_cast<QMouseEvent*>(event); 
     emit mouseEventDetected(e->x(), e->y()); 
    } 

    if (t == QEvent::DragMove) { 
     QDragMoveEvent* e = static_cast<QDragMoveEvent*>(event); 
     emit mouseEventDetected(e->pos().x(), e->pos().y()); 
    } 
    return QObject::eventFilter(watched, event); 
} 

그런 다음 화면, 창, (필요 무엇을 적으로 좌표를 변환 할 수 있습니다 ...)

+0

나는 당신의 접근법을 수정하려고 시도했지만 불행히도 다음과 같은 경우에는 작동하지 않습니다. - 화면에 MouseArea가 있으며, 그것을 누르고 드래그를 시작합니다. 마우스가이 마우스 영역을 떠나면 마우스 이동 이벤트가 중지되므로 다른 항목은 마우스 위치 업데이트를 가져 오지 않습니다. – evilkonrex

+0

코드를 게시 할 수 있습니까? 나는 그 문제가 없다. Ofc. 마우스가 응용 프로그램을 나가면 이벤트를 수신하지 않습니다. – derM

+1

원본 게시물에 코드를 추가하고 있습니다. – evilkonrex

0

당신이 글로벌 마우스 위치를 조회해야하는 장소의 몇 가지있다, 나는 당신이 mapToGlobal 또는 mapToItem 방법을 사용하는 것이 좋습니다 것입니다.

+0

문제는 마우스가 현재 존재하는 mouseAreas 밖에있을 때 마우스 위치를 확인해야하는 경우입니다. 그리고이 경우 (그 것 같다) 나는 현재 마우스 위치를 업데이트 할 수있는 마우스 움직임 이벤트를 얻지 못하고있다. – evilkonrex

0

저는 C++ 측에서 커서의 좌표를 얻을 수 있다고 믿습니다. this question에 대한 답변을보십시오. 질문은 문제와 관련이 없지만 해결책은 잘 작동합니다.

내 측면에서 MouseArea없이 직접 mousePosProvider.cursorPos()을 호출하여 전역 좌표를 가져올 수있었습니다.

+0

이것은 쿼리하는 데는 잘 작동하는 것처럼 보이지만 바인드 할 수는 없습니다. MouseArea에서 드래그 할 때 문제가 발생합니다 (원래 게시물에 추가됨).이 경우 마우스 이동 이벤트가 수신되지 않고 현재 마우스 위치를 업데이트 할 수 없습니다. – evilkonrex