2015-08-16 3 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()); 

То, что я ожидал, что только один экран вернется действительное положение, так как курсор находится только на одном экране, а не на обоих. Но это не так, то оба позиций (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

Вы используете виртуальный рабочий стол? Двойная голова? – 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.Даже если вы берете точку с экрана1 (с pos (QScreen *)), она возвращает 0. – armitage

+0

Используете ли вы Windows? Он работает здесь в Windows 10. –

+0

Я использую Getoo, с KDE и Awesome в качестве оконного менеджера. Возможно, это проблема конфигурации. Рафаэль, вы могли бы поделиться выходом и кодом, который вы выполнили? – armitage

0

Sice, кажется, это не может быть сделано с Qt (по крайней мере, с моей конфигурацией системы, и похоже, что и в Windows) я решил использовать libX11 для реализации, которая работает как шарм.

Это не идеальное решение, потому что я хотел использовать только Qt, но он работает.

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(); 
} 
+0

в этом коде, я считаю, что cursorPos следует переименовать pos. – Dave

+0

@Dave Исправлено, спасибо! – Lekensteyn

+0

Какой заголовок мне нужен для этой функции cursorPosToNative? Кажется, он не существует в Qt 5.9.3? – Vertigo

0

Это может показаться тривиальным решением, но на моем KDE так ли (я столкнулся с теми же проблемами изначально). Если вы хотите, чтобы определить локальные координаты мыши относительно виджета (это будет в пикселях устройства и относительно верхнего левого угла виджета, я считаю), вы можете использовать

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

т.е. называют this->mapFromGlobal.

Смежные вопросы