[qt 4.8]
为了获得正确的窗口尺寸(包括其框架),我执行以下操作(如此处所述,请参阅 Daniel Hedberg 的评论)。
mainWindow.move(-50000, -50000);
mainWindow.show();
// do something with the window dimensions
mainWindow.move(0, 0);
mainWindow.show()
这工作正常,但是,我对
move(0,0)
调用有问题:它使窗口always出现在位置(0,0),而我希望有默认行为,这只是应用程序向窗口管理器建议 (0,0) 是放置窗口的好位置,并且 WM 可能会决定在必要时移动它以避免重叠。换句话说,我想切换回 Qt 的默认行为,就好像根本没有调用 move
一样。
我怎样才能做到这一点?
一种解决方案是存储 Windows 原始位置并使用它。为了额外的安全性(如果屏幕分辨率发生变化),请检查整个窗口是否仍然适合屏幕,如果不适合,请移动甚至调整大小。
一个巧妙的替代方案是创建并打开相同大小的空的、可能是透明的虚拟窗口,并查看它的位置。然后将原件移到那里并关闭虚拟的。仔细阅读你的问题,我认为这会满足你的需求。
我不知道 Qt 方法可以要求窗口管理器重新定位窗口,因此如果您确实需要,请指定操作系统等详细信息。
查看 Qt 的源代码,我现在可以部分回答我自己的问题:要将对
move
的调用转换为定位建议而不是请求,请执行以下操作:
mainWindow.move(100, 100);
mainWindow.setAttribute(Qt::WA_Moved, false);
mainWindow.show();
我已经使用 Qt 4.8.4 在 X11 下测试了代码,希望它也适用于其他平台。
不幸的是,这并不能解决我遇到的问题,即使用
show
获取屏幕外窗口的(装饰的)尺寸,然后将其移动到屏幕,再次调用 show
。似乎第一次调用 show
直接设置了特定于平台的窗口管理器标志,这些标志在第二次调用中没有完全重置和重新评估。实际上,我会认为这是 Qt 中的一个错误,所以我会相应地报告它。
您应该处理桌面调整大小,也许像:
#include <QApplication>
#include <QDesktopWidget>
// ...
// Limits position to Screen.
connect(qApp->desktop(), &QDesktopWidget::resized, this, [&, this](int desktopId) -> void {
if ( ! qApp) {
return; // App is terminating.
}
QDesktopWidget *desktopInfo = qApp->desktop();
if ( ! desktopInfo) {
return; // God knows.
}
if ( desktopInfo->screenNumber(this) == desktopId )
{
const QRect &max = desktopInfo->screenGeometry(this);
QRect current = this->geometry();
if (current.right() > max.right())
current.moveRight(max.right());
else if (current.left() < max.left())
current.moveLeft(max.left());
if (current.bottom() > max.bottom())
current.moveBottom(max.bottom());
else if (current.top() < max.top())
current.moveTop(max.top());
}
});
您可以对内部的移动事件执行类似的操作:
void moveEvent(QMoveEvent *) override;
注意,仅从 Qt5 开始支持 Lambda,但您可以更改上述内容以不使用 Lambda。