web-dev-qa-db-ja.com

Qt 5、画面でのマウスの位置を取得する

まず、関連する投稿を見つけたということをお伝えします Qtで画面上のマウスの位置を取得する方法は? ですが、「うまくいきませんでした」。いくつかのテストを行ったが、期待した結果が得られなかったため、新しい投稿を作成して、行ったテストについて説明し、別の解決策を見つけることにしました。

それは私がテストをするために使用したコードです:

QScreen *screen0 = QApplication::screens().at(0);
QScreen *screen1 = QApplication::screens().at(1);

printf("screen0 %s \n", screen0->name().toStdString().c_str());
printf("screen1 %s \n", screen1->name().toStdString().c_str());

// Position on first screen.
QPoint pos0 = QCursor::pos(screen0);

// Position on second screen.
QPoint pos1 = QCursor::pos(screen1);

printf("pos 0: %d, %d \n", pos0.x(), pos0.y());
printf("pos 1: %d, %d \n", pos1.x(), pos1.y());

// Get position without screen.
QPoint pos = QCursor::pos();
printf("pos: %d, %d \n", pos.x(), pos.y());

私が期待していたのは、カーソルが両方の画面ではなく1つの画面にあるため、1つの画面だけが有効な位置を返すということです。しかし、そうではありません、両方の位置(pos0およびpos1)は、出力からわかるように、まったく同じ値です。

screen0 DVI-D-0 
screen1 HDMI-0 
pos 0: 1904, 1178 
pos 1: 1904, 1178 
pos: 1904, 1178 

どちらの位置も同じ値なので、どちらの画面がカーソルなのかわかりません。これは正常な動作なのかバグなのかはわかりません。ドキュメントの引数がマウスのある画面でない場合、ドキュメントには何が起こるのかが書かれていないためです。

私の考えは、マウスが置かれている画面に対して(選択された画面を検出する必要があるQtデーモンによって実行される)アプリケーションを開く/起動することです。 libX11でそれが可能であることを知っています、私は過去にそれをしたので、Qt 5で作業する必要があり、私は理解できませんQtで選択した画面を検出する方法.

また、QApplicationおよびQDesktopWidgetクラスを使用して、運が悪かった他のテストも行いました。

13
armitage

それは本当に奇妙です。回避策として、これを試すことができます:

QPoint globalCursorPos = QCursor::pos();
int mouseScreen = qApp->desktop()->screenNumber(globalCursorPos);

これで、カーソルが置かれている画面がわかりました。次に、その画面内でカーソル位置を見つけて、次のようにします。

QRect mouseScreenGeometry = qApp->desktop()->screen(mouseScreen)->geometry();
QPoint localCursorPos = globalCursorPos - mouseScreenGeometry.topLeft();
8
Rafael Monteiro

これは簡単な解決策のように思えるかもしれませんが、私のKDEでは機能します(元々同じ問題に遭遇しました)。ウィジェットに関するローカルマウス座標を決定する場合(これはデバイスピクセルであり、ウィジェットの左上隅を基準とする)、次のように使用できます。

QWidget::mapFromGlobal(QCursor::pos());

つまり、this->mapFromGlobal

4
GPMueller

現在の画面を把握するには、繰り返し QGuiApplication::screens() して、カーソルが画面の geometry に収まるかどうかを確認します。

ネイティブカーソル位置を計算するためのより複雑な例を次に示します(高DPI画面での作業に必要な追加の作業に注意してください)。

QPoint getNativeCursorPosition()
{
    QPoint pos = cursorPosToNative(QCursor::pos());

    // Cursor positions from Qt are calculated in a strange way, the offset to
    // the Origin of the current screen is in device-independent pixels while
    // the Origin itself is native!

    for (QScreen *screen : QGuiApplication::screens()) {
        QRect screenRect = screen->geometry();
        if (screenRect.contains(pos)) {
            QPoint Origin = screenRect.topLeft();
            return Origin + (pos - Origin) * screen->devicePixelRatio();
        }
    }

    // should not happen, but try to find a good fallback.
    return pos * qApp->devicePixelRatio();
}
2
Lekensteyn

Qtでは(少なくとも私のシステム構成では、Windowsでもそうであるように)それを実行できないようです。libX11を使用してその実装を作成することにしました。これは魅力のように機能します。

Qtのみを使用したかったので、理想的なソリューションではありませんが、動作します。

0
armitage

これはあなたのために働くかもしれませんか?それは私のためにした

QDesktopWidget *widget = QApplication::desktop(); QPosition globalCursorPosition = widget->cursor().pos();

0
samarth