2017-11-23 121 views
0

QMLで小さなPoCをプログラミングしています。私のコードのいくつかの場所では、グローバルなマウス位置(例えば、シーンやゲームウィンドウ内のマウスの位置)にバインド/照会する必要があります。マウスが私が今までに定義したMouseAreasの外にある場合でも。QMLでのグローバルなマウス位置の照会

周囲を見回すと、画面全体が別のMouseAreaで覆われている可能性があります。ほとんどの場合、ホバリングが有効になっています。次に、下にあるマウス領域に準手動伝播(ホバー)イベントを処理する必要があります。

私はここに何か不足していますか?これはかなり一般的なケースのようです - それを達成するためのよりシンプルでエレガントな方法がありますか?

EDIT: 最も問題のあるケースは、MouseAreaの外にドラッグしているようです。以下は最小限の例です(V-PlayコンポーネントとderMの答えからのマウスイベントスパイを使用しています)。画像をクリックしてMouseAreaの外にドラッグすると、マウスイベントがもう発生しなくなり、以下のDropAreaがない限り、位置を更新できなくなります。

MouseEventSpyは、答えの1つに応じて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'の修正コードを提供できますか? '... && event->自発的な()){ QMouseEvent *私を:;' 、その後 '無効mouseEventDetected(int型のx、int型のY): – derM

+1

それはほとんど変更されていないですが、私は、信号のプロトタイプを変更しました=(QMouseEvent *)イベント。 emit mouseEventDetected(me-> globalX()、me-> globalY()); } ' – evilkonrex

+0

これは' Drag.dragType'に関連しているようです。コメントアウトされていれば、動作するようです。解決策が見つかるかどうかがわかります。 – derM

答えて

1

すべてのマウスイベントが通過するQGuiApplicationにeventFilterをインストールできます。これを行うにはどのように

がリンクソリューションではhere

に記載されている信号を発するとき、私は、マウスの位置に関する情報をドロップします。しかし、メソッドに渡されたQEventQMouseEventにキャストして、それをパラメータとしてパラメータに追加することで、簡単に情報を取得できます。

リンクされた回答では、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

あなたはグローバルなマウスの位置を照会する必要がある場所の唯一のカップルを持っているように、私はあなたがmapToGlobalmapToItemメソッドを使用することをお勧めします。

+0

問題は、マウスが現在存在するmouseAreasの外にあるときにマウスの位置を確認する必要があることがあります。そして、この場合(私は)、私は現在のマウスの位置を更新することができるマウスの動きのイベントを取得していないよ。 – evilkonrex

0

私はあなたがC++側からカーソルの座標を得ることができると信じています。 this questionの回答を見てください。問題はあなたの問題に関係しませんが、解決策も同様に機能します。

私の側では、MouseAreaなしで直接mousePosProvider.cursorPos()を呼び出してグローバル座標を取得できました。

+0

これはクエリにはうまくいくようですが、バインドできません。 MouseAreaからドラッグすると、元の投稿に追加した問題が発生します。この場合、マウス移動イベントは受け付けられず、現在のマウス位置を更新するものはありません。 – evilkonrex

関連する問題