Прежде всего, я хотел бы отметить, что я нашел этот пост Как получить положение мыши на экране в 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
занятия без удачи.
Это действительно странно. В качестве обходного пути вы можете попробовать это:
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());
то есть звонок this->mapFromGlobal
,
Чтобы выяснить, на каком экране вы находитесь, вы можете выполнить QGuiApplication::screens()
и проверьте, помещается ли курсор в геометрия экрана.
Вот более сложный пример для вычисления собственной позиции курсора (обратите внимание на дополнительную работу, необходимую для работы с экранами с высоким разрешением):
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, но оно работает.