Qt如何枚举屏幕?

时间:2019-01-24 16:29:09

标签: c++ windows qt qt5 multiple-monitors

今天我发现Qt枚举屏幕(QGuiApplication::screens)的顺序与Windows(EnumDisplayMonitors)中的顺序不同。

为了在混合Windows API和Qt时考虑到这种差异,背后的逻辑是什么?例如,如果需要在屏幕#2中显示某些内容(使用Windows枚举)。

这是我用来测试的代码(in 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作为3的主屏幕,1(1280x1024),3(1920x1080),*** 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) (1920x1080)

结果:

EnumDisplayMonitors

1 个答案:

答案 0 :(得分:4)

据我所见,在不同系统中,QGuiApplication::screens按照“显示设置”中定义的顺序返回监视器,而QGuiApplication::primaryScreen始终在第一位置显示主屏幕(实际上, EnumDisplayMonitors只需这样做:返回第一个元素)。

在源代码中,Windows Qt也使用it.skip()函数,但是基本上将主屏幕移到了第一位置(实际上是将主屏幕插入到第一位置,而在主屏幕的末尾插入列出其他任何监视器。

因此,主屏幕将位于第一个位置,索引低于主屏幕的屏幕将被移动一个位置,而其余屏幕将与索引匹配。


从代码注释中摘录,如果在执行应用程序期间更改了主屏幕,则Qt将无法报告更改。

  

请注意,此政策的副作用是无法更改Qt报告的主屏幕,除非我们要删除所有现有屏幕并在主屏幕发生更改时再次添加它们。