2015-08-16 151 views
8

首先,我想提一提的是,我发现相关的帖子How to get the mouse position on the screen in Qt?,但它对我来说“只是没有用”。我做了一些测试,结果没有像我预期的那样工作,所以我决定做一个新的帖子来谈论我做的测试并寻找替代解决方案。Qt 5,获得鼠标在屏幕上的位置

是这样的代码,我用来做测试:

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 

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

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

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

+0

您使用的是虚拟桌面吗?双头? – peppe

回答

3

这真的很奇怪。作为一种变通方法,你可以试试这个:

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

现在你知道哪个屏幕光标,然后你会发现,屏幕中的光标位置这样做:

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

我试过了,但它总是返回屏幕0。即使你从screen1(pos(QScreen *))取得了这个点,它也会返回0. – armitage

+0

你使用的是Windows吗?它在Windows 10上工作。 –

+0

我使用Getoo,KDE和Awesome作为窗口管理器。也许这是一个配置问题。拉斐尔,你能分享输出和你执行的代码吗? – armitage

0

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

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

2

要弄清楚你是哪个屏幕,你可以遍历t 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(); 
} 
+0

在这段代码中,我认为cursorPos应该改名为pos。 – Dave

+0

@Dave固定,谢谢! – Lekensteyn

+0

这个'cursorPosToNative'函数需要哪个头文件 - 它似乎不存在于Qt 5.9.3中? – Vertigo

0

这似乎是一个简单的解决方案,但是在我的KDE它作品(我最初碰到相同的问题)。 如果你想确定本地鼠标相对于一个部件坐标(这将是设备像素相对于widget的左上角我相信),你可以使用

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

即致电this->mapFromGlobal

相关问题