如何强制QDesktopWidget::screenGeometry返回更新的几何值

How to force QDesktopWidget::screenGeometry to return updated geometry values

本文关键字:何值 更新 screenGeometry 何强制 QDesktopWidget 返回      更新时间:2023-10-16

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

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

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

问题是QDesktopWidget::screenGeometry()在分辨率发生变化之前返回维度

在这个阶段,Qt事件循环还没有启动。

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

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

所以问题是:

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

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

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

我怀疑除了等待Qt事件循环启动并接收信号之外,还有其他选择。您可以通过将窗口隐藏直到接收到信号之后来避免这种难看的效果。

这是我结束做的,就在分辨率改变后:

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()的下一次调用将返回期望的值