代码之家  ›  专栏  ›  技术社区  ›  cbuchart

Qt如何枚举屏幕?

  •  6
  • cbuchart  · 技术社区  · 6 年前

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

    这种差异背后的逻辑是什么,以便在混合WindowsAPI和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 (1920年X1080) 1 (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)
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   cbuchart    6 年前

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

    在Windows中,qt还使用 EnumDisplayMonitors(EnumDisplayMonitors) 功能,但基本上将主屏幕移动到第一个位置(它实际上在第一个位置插入主屏幕,同时在列表末尾插入任何其他监视器)。

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


    从代码的注释中可以看出,如果在应用程序执行期间主屏幕发生了更改,qt将无法报告更改。

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