Как Qt перечисляет экраны?
Сегодня я обнаружил, что порядок, как Qt перечисляет экраны (QGuiApplication::screens
) отличается от порядка в Windows (EnumDisplayMonitors
).
Какова логика, лежащая в основе этого различия, чтобы учесть это при смешивании Windows API и Qt? Например, если требуется показать что-то на экране № 2 (используя перечисление Windows).
Вот код, который я использовал для тестирования (также доступен в GitHub):
#include <qapplication.h>
#include <qdebug.h>
#include <qscreen.h>
#include <Windows.h>
#include <iostream>
std::ostream& operator<<(std::ostream& of, const RECT& rect)
{
return of << "RECT(" << rect.left << ", " << rect.top << " " << (rect.right - rect.left) << "x" << (rect.bottom - rect.top) << ")";
}
BOOL CALLBACK printMonitorInfoByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
auto index = (int*)dwData;
std::cout << ++*index << " " << *lprcMonitor << std::endl;
return TRUE;
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
qDebug() << "*** Qt screens ***";
const auto screens = qApp->screens();
for (int ii = 0; ii < screens.count(); ++ii) {
qDebug() << ii + 1 << screens[ii]->geometry();
}
qDebug() << "*** Windows monitors ***";
int index = 0;
EnumDisplayMonitors(NULL, NULL, printMonitorInfoByHandle, (LPARAM)&index);
return 0;
}
Моя конфигурация дисплеев слева направо 2
(1280x1024), 3
(1920x1080), 1
(1920x1080), будучи моим основным экраном 3
,
Результаты:
*** Qt screens ***
1 QRect(0,0 1920x1080)
2 QRect(1920,233 1920x1080)
3 QRect(-1280,47 1280x1024)
*** Windows monitors ***
1 RECT(1920, 233 1920x1080)
2 RECT(-1280, 47 1280x1024)
3 RECT(0, 0 1920x1080)
1 ответ
Насколько я мог видеть в разных системах, EnumDisplayMonitors
возвращает мониторы в порядке, определенном в настройках дисплея, а QGuiApplication::screens
всегда показывает основной экран в первой позиции (на самом деле, QGuiApplication::primaryScreen
просто сделайте это: верните первый элемент).
Глядя на исходный код, в Windows Qt также использует EnumDisplayMonitors
функция, но в основном перемещает основной экран в первую позицию (он фактически вставляет в первую позицию основной экран, в то время как вставляет в конец списка любой другой монитор).
Таким образом, основной экран будет на первой позиции, экраны с индексом ниже, чем у основного экрана, будут смещены на одну позицию, а остальные будут соответствовать индексу.
В качестве примечания, взятого из комментариев кода, если основной экран изменяется во время выполнения приложения, Qt не может сообщить об этом изменении.
Обратите внимание, что побочным эффектом этой политики является то, что нет способа изменить основной экран, о котором сообщает Qt, если только мы не хотим удалить все существующие экраны и добавить их снова при каждом изменении основного экрана.