首先,我想提一下,我发现相关的帖子How to get the mouse position on the screen in 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());
我所期待的是,只有一个屏幕会返回一个有效位置,因为光标只在一个屏幕上,而不在两个屏幕上。但情况并非如此,两个位置(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
类进行了其他测试,没有运气。
答案 0 :(得分:7)
这真的很奇怪。作为一种解决方法,您可以尝试这样做:
QPoint globalCursorPos = QCursor::pos();
int mouseScreen = qApp->desktop()->screenNumber(globalCursorPos);
现在您知道光标所在的屏幕。然后您可以在该屏幕中找到光标位置:
QRect mouseScreenGeometry = qApp->desktop()->screen(mouseScreen)->geometry();
QPoint localCursorPos = globalCursorPos - mouseScreenGeometry.topLeft();
答案 1 :(得分:2)
要确定您所在的屏幕,您可以迭代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 :(得分:2)
这可能看起来像一个简单的解决方案,但在我的KDE上它可行(我最初遇到了同样的问题)。 如果你想确定关于一个小部件的本地鼠标坐标(这将是设备像素并且相对于我认为的小部件的左上角)你可以使用
QWidget::mapFromGlobal(QCursor::pos());
即。致电this->mapFromGlobal
。
答案 3 :(得分:1)
这可能对您有用? 对我有用
QDesktopWidget *widget = QApplication::desktop();
QPosition globalCursorPosition = widget->cursor().pos();
答案 4 :(得分:0)
似乎它不能用Qt完成(至少在我的系统配置中,似乎也在Windows中)我决定使用libX11来实现这个实现,就像魅力一样。 / p>
这不是一个理想的解决方案,因为我只想使用Qt,但它确实有效。
答案 5 :(得分:0)
使用QML,您可以使用“屏幕QML类型”的属性:
Screen.virtualX:虚拟桌面中屏幕的x坐标。
Screen.virtualY:虚拟桌面中屏幕的y坐标。
import QtQuick 2.6
import QtQuick.Window 2.2
console.log("Pos x : " + Screen.virtualX )
console.log("Pos y : " + Screen.virtualY )
这与单屏幕以及多显示器系统一起使用。
答案 6 :(得分:0)
我最近在 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();
我不确定这是否适用于其他平台。