经过几个月的尝试,搜索,查看代码等等,我无法找到在QT中正确定位新窗口的解决方案。在我最基本的情况下,我只想获得窗口的最终大小并将其置于鼠标下方。它将被移动以确保窗口的任何部分都不在屏幕之外。我不希望窗口出现然后移动到位,这会产生视觉震动,特别是桌面FX打开时。
我遇到的问题,并非所有问题都有适当的解决方案:
在之前显示窗口之前,并不总是填充frameGeometry。
frameGeometry有时完全错误,特别是在Windows 7上。
在显示之前,无法知道是应用sizeHint还是大小,或者介于两者之间。也就是说,尺寸政策似乎不可预测。
请注意,我知道如何保存/恢复以前创建的窗口的几何体。尽管这里存在QT缺陷,但我还是有一个可行的解决方案。
另请注意,我无法使用窗口管理器默认放置。对于多显示器设置中的非MDI应用程序,它们的位置非常糟糕(通常甚至与鼠标不在同一台显示器上)。
我还想避免对所有小部件和对话框进行子类化以实现解决方案,因为它不是通用的。如果这是唯一可能的方式,那么我愿意考虑它(如果事件过滤器也不是一个选项)。
有没有人有可行的解决方案?
答案 0 :(得分:6)
编辑看起来更科学:我已将任意调用次数更改为
processEvents
带有一个检查返回值的循环。
再次编辑:新版本似乎不安全:它可能会卡在循环中。所以我对迭代次数设置了限制。
<强>原始强>
告诉我怎么回事儿。如果允许我引用我自己的代码:
// BIG PAIN: We want to get the dialog box to caluclate its own size. But there is
// no simple way to do this. The following seems to work, but only if processEvents
// is called at least twice. God knows why:
setAttribute (Qt::WA_DontShowOnScreen, true) ; // Prevent screen flicker
show() ;
QEventLoop EventLoop (this) ;
for (int i = 0 ; i < 10 ; i++)
if (!EventLoop.processEvents()) break ;
hide() ;
setAttribute (Qt::WA_DontShowOnScreen, false) ;
int x = 99 ; // whatever
int y = 99 ; // whatever
// Make sure it fits on the screen
QRect ScreenRect = qApp -> desktop() -> availableGeometry (ApplicationData -> mainWindow) ;
if (x + frameGeometry().width() > ScreenRect.right())
x = ScreenRect.right() - frameGeometry().width() ;
if (x < ScreenRect.x()) x = ScreenRect.x() ;
if (y + frameGeometry().height() > ScreenRect.bottom())
y = ScreenRect.bottom() - frameGeometry().height() ;
if (y < ScreenRect.y()) y = ScreenRect.y() ;
move (x, y) ;
尝试此操作,对processEvents
进行不同数量的调用。 (在这些调用中,各种子窗口小部件和子子窗口小部件以递归方式调整大小。)
答案 1 :(得分:1)
关于在显示窗口之前无法查询窗口大小的问题,有一个简单的解决方法。在显示窗口之前,您可以将窗口移动到屏幕外的某个位置。例如,如果要将主窗口置于主屏幕中心而不闪烁,请执行以下操作:
MainWindow mainWindow;
QRect primaryScreenGeometry(QApplication::desktop()->screenGeometry());
mainWindow.move(-50000,-50000);
mainWindow.show();
mainWindow.move((primaryScreenGeometry.width() - mainWindow.width()) / 2.0,
(primaryScreenGeometry.height() - mainWindow.height()) / 2.0);
我只在Windows XP和Qt 4.8.x上测试过这段代码。希望它也适用于其他平台。
答案 2 :(得分:-1)
您是否尝试过激活布局?它迫使它计算尺寸和位置
QLayout ::激活()
此调用后,您的小部件应具有正确的大小。