Qt 如何枚举屏幕?

Posted

技术标签:

【中文标题】Qt 如何枚举屏幕?【英文标题】:How does Qt enumerate screens? 【发布时间】:2019-01-24 16:29:09 【问题描述】:

今天发现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 (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 函数但基本上将主屏幕移动到第一个位置(它实际上是在第一个位置插入主屏幕,而在列表末尾插入任何其他显示器)。

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


作为旁注,取自代码的 cmets,如果主屏幕在应用程序执行期间发生更改,Qt 无法报告更改。

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

【讨论】:

以上是关于Qt 如何枚举屏幕?的主要内容,如果未能解决你的问题,请参考以下文章

QT枚举类型与字符串类型相互转换

可枚举的 Qt 小部件

是否可以使用 Qt 类枚举网络根?

Qt4 QSettings保存枚举值(例如Qt::CheckState)

Qt每天一例13.枚举转字符串

Qt:meta.enumeratorCount() 没有元数据用于 Q_OBJECT 中的枚举,为啥?