0

我正在尝试在QWidget移动时关注另一个。

特别是,我有一个QMainWindow带按钮的。此按钮显示一个QWidget,即“追随者”。现在我希望追随者QMainWindow在我拖动它时真正跟随它。

我已经重新实现QMainWindow::moveEvent()了更新follower的位置,但是在移动和 follower 之间存在巨大的延迟。它有效,但它看起来像是 1990 年的东西!我实际上可以拖动窗口,当我停下来时,跟随者会移动。

我怎样才能让追随者“坚持” QMainWindow?当我拖动它时,我希望它看起来真的粘在窗户上!

有什么提示吗?

干杯!

4

2 回答 2

0

文档说关于 moveEvent:

当小部件收到此事件时,它已经在新位置。

所以也许更好的主意是定期检查(例如使用QTimer) mainWindow 的位置,如果它发生变化则移动跟随者。

在您发表评论后,另一个想法是重新实现:

void MainWindow::mouseMoveEvent(QMouseEvent *event)

在没有系统栏的情况下使用自定义小部件(即新表单或使用 Qt::FramelessWindowHint),拖动将通过重新实现的自定义栏完成,在这种情况下,您将一起移动 mainWindow 和跟随器。

于 2013-06-26T13:44:26.020 回答
0

正如手册中明确指出的:

当小部件收到这个事件时,它已经在新的位置

因此,如果您等待moveEvent触发,则在您完成拖动主窗口之前不会发生任何事情。
如果你容忍你的随从窗口坐在那里,而它的伙伴被拖着走,它会工作得很好。

这种大约 1990 年的感觉并非巧合。Windows 在屏幕上移动事物的古怪方式确实是由于传统策略可以追溯到那些试图在屏幕上经常复制位图足以让 PC 瘫痪的日子。

Qt 不提供开箱即用的更具反应性的解决方案的原因是底层窗口管理器不同意它的完成方式。我不知道 X11 是如何处理它的,但 Windows 确实把它搞得一团糟。大学生编程,真的。

无论如何,从 windows 程序看,你会收到一个WM_ENTERSIZEMOVE,然后被喂一个未知数量的WM_MOVING(你可能想要过滤这些以避免过于频繁地移动你的追随者窗口),直到你得到一个WM_LEAVESIZEMOVE最终的通知。
您可以重载方便的WinEvent方法来监视这些本机消息。 WM_LEAVESIZEMOVE不是强制性的,您也可以等待标准的 Qt moveEvent

我强烈建议您不要在 Google 上找到各种黑客攻击。偷偷窥视事件队列并检测,例如,单击窗口的系统栏,监视原始鼠标事件等。尽管您最终可能会使其正常工作,至少在简单的情况下,尝试重写窗口的一小部分经理,尤其是像 Win32 这样蹩脚和过时的经理,会坚定地反复自找麻烦。

无论如何,在我看来,为了获得轻微的外观和感觉改进而跳过所有这些障碍是绝对不值得的。

于 2020-01-12T17:32:22.710 回答