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

我所期望的是,只有一个屏幕会返回一个有效的位置,因为光标只在一个屏幕上,而不是在两个屏幕上。但事实并非如此,两个位置(pos0pos1)具有完全相同的值,正如我们在输出中看到的那样:

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

因为两个位置有相同的值,我不知道光标在哪个屏幕上。我不知道这是正常行为还是错误,因为文档没有说明当screen参数不是鼠标所在的屏幕时会发生什么。

我的想法,是打开/启动一个应用程序(由Qt守护进程执行,必须检测选定的屏幕)到屏幕上的鼠标。我知道,与libX11这是可能的,因为我做了在过去,但我需要与Qt 5工作,我不知道如何做检测选定的屏幕与Qt。

我还做了其他测试,使用QApplicationQDesktopWidget类没有运气

这真的很奇怪。作为一种解决方法,您可以尝试这样做:

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

现在您知道光标在哪个屏幕上了。然后你可以在屏幕上找到光标的位置,这样做:

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

这似乎是一个微不足道的解决方案,但在我的KDE上它可以工作(我最初遇到了同样的问题)。如果您想确定相对于小部件的本地鼠标坐标(我相信这将以设备像素为单位,并且相对于小部件的左上角),您可以使用

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

。call this->mapFromGlobal .

这可能对你有用?

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

要确定您在哪个屏幕上,您可以遍历QGuiApplication::screens()并检查光标是否适合屏幕的几何形状。

下面是一个计算本地光标位置的更复杂的示例(注意,使用高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();
}

因为它似乎不能用Qt完成(至少在我的系统配置中,似乎也在Windows中),我决定使用libX11来实现,它像魅力一样工作。

这不是一个理想的解决方案,因为我只想使用Qt,但它工作。

使用QML你可以使用屏幕QML的属性类型:

屏幕。virtualX:虚拟桌面中屏幕的x坐标。

屏幕。virtualY:虚拟桌面中屏幕的y坐标。

import QtQuick 2.6
import QtQuick.Window 2.2
console.log("Pos x : " + Screen.virtualX )
console.log("Pos y : " + Screen.virtualY )

这适用于单屏幕和多监视器系统。

我最近在Qt 5.15 + Windows +混合DPI上遇到了类似的问题,需要在QWindow对象中进行此工作。

QScreen* primaryScreen = QGuiApplication::primaryScreen();
QScreen* thisScreen = screen();
qreal primaryDPR = primaryScreen->devicePixelRatio();
qreal thisDPR = thisScreen->devicePixelRatio();
qreal scale = thisDPR / primaryDPR;
QPoint pos = scale  * QCursor::pos();

我不确定这是否适用于其他平台

相关内容

  • 没有找到相关文章

最新更新