【问题标题】:How to force QDesktopWidget::screenGeometry to return updated geometry values如何强制 QDesktopWidget::screenGeometry 返回更新的几何值
【发布时间】:2014-05-27 14:21:24
【问题描述】:

我有一个 QT 应用程序,它在启动时更改屏幕分辨率(通过 unix 中的 xrandr 或通过 OSX 上的 CGConfigureDisplayMode)

一旦屏幕分辨率更改完成并成功,应用程序将继续。

然后它使用QApplication::desktop()->screenGeometry(int) 来检索各种屏幕的大小。

问题在于QDesktopWidget::screenGeometry() 返回分辨率更改发生之前的尺寸。

在这个阶段,Qt 事件循环还没有开始。

我当然会在 Qt 事件循环运行后接收QDesktopWidget::resized(int) 信号,然后调用QDesktopWidget::screenGeometry 将返回更新后的维度。但到那时为时已晚。

我可以在接收到信号后强制刷新屏幕,然后重新计算所有内容,但这会产生丑陋的效果,因为您看到窗口首先以错误的尺寸显示,然后再使用正确的尺寸。

所以问题是:

如何确保QDesktopWidget::screenGeometry() 返回实际值,而不是应用程序启动时的值。

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    最终,您可以在创建 MainWindow 之前在 main.cpp (int main()) 中实现桌面分辨率切换。如果这是可能的,您可以切换并且您的窗口将具有正确的尺寸。您可能也可以在那里运行一个简短的自定义事件循环。

    作为最后的手段,将您的应用程序拆分为 2 个进程。第一个将设置屏幕分辨率,也将被隐藏。分辨率切换成功后,您的应用程序将调用从正确尺寸开始的真实应用程序。

    【讨论】:

      【解决方案2】:

      我怀疑除了等到 Qt 事件循环启动并接收信号之外还有其他选择。您可以通过在收到信号之前隐藏窗口来避免丑陋的效果。

      【讨论】:

      • 更糟糕的是,使用 Qt 4.8.5 和 Maverick,似乎没有发送屏幕更改信号。
      【解决方案3】:

      这就是我在分辨率更改后结束的操作:

      QEventLoop loop;
      QTimer timer;
      QDesktopWidget *desktop = QApplication::desktop();
      
      timer.setSingleShot(true);
      QObject::connect(&timer, SIGNAL(timeout()),
                       &loop, SLOT(quit()));
      QObject::connect(desktop, SIGNAL(resized(int)),
                       &loop, SLOT(quit()));
      QObject::connect(desktop, SIGNAL(workAreaResized(int)),
                       &loop, SLOT(quit()));
      timer.start(300); //300ms maximum wait
      loop.exec();
      

      这个短暂的等待,刚好够 Qt 框架处理分辨率的变化,下一次调用QDesktopWidget::screenGeometry() 将返回期望值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-23
        • 2021-10-14
        • 1970-01-01
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多