5

经过数月的尝试、搜索、审查代码等。我无法找到在 QT 中正确定位新窗口的解决方案。在我最基本的情况下,我只是想获得窗口的最终大小并将其置于鼠标下方。它将被移动以确保窗口的任何部分都不在屏幕之外。我不希望窗口出现然后移动到适当的位置,这会产生视觉上的震动,尤其是在打开桌面 FX 的情况下。

我遇到的问题,并不是所有的都有合适的解决方案:

  1. 在之前显示窗口之前,并不总是填充 frameGeometry。

  2. frameGeometry 有时完全错误,尤其是在 Windows 7 上。

  3. 在显示之前,无法知道是否会应用 sizeHint 或 size,或者介于两者之间的其他内容。也就是说,规模政策似乎不可预测。

请注意,我知道如何保存/恢复以前创建的窗口的几何图形。尽管这里也有 QT 缺陷,但我有一个可行的解决方案。

另请注意,我不能使用窗口管理器的默认位置。对于多显示器设置上的非 MDI 应用程序,它们的位置很糟糕(通常甚至与鼠标不在同一显示器上)。

我还想避免为了实现解决方案而对所有小部件和对话框进行子类化,因为它不是通用的。如果这是唯一可能的方法,那么我愿意考虑它(如果事件过滤器也不是一个选项)。

有没有人有好的可行的解决方案?

4

3 回答 3

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. (在这些调用中,各种子小部件和子小部件递归地调整自身大小。)

于 2011-03-24T10:18:46.037 回答
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 上测试过这段代码。希望它也适用于其他平台。

于 2012-12-17T00:15:35.340 回答
-1

您是否尝试过激活布局。它迫使它计算大小和位置

QLayout::activate()

在此调用之后,您的小部件应该具有正确的大小。

于 2011-08-26T09:36:49.460 回答