【问题标题】:Following a QWidget while moving移动时跟随 QWidget
【发布时间】:2013-06-26 13:34:06
【问题描述】:

我正在尝试让QWidget 在移动时跟随另一个。

特别是,我有一个带有按钮的QMainWindow。此按钮显示QWidget,即“关注者”。现在我希望 关注者 在我拖动 QMainWindow 时实际关注它。

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

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

有什么提示吗?

干杯!

【问题讨论】:

  • 在为窗口设置新位置后尝试调用QApplication::processEvents()

标签: qt mouseevent mousemove qwidget qmainwindow


【解决方案1】:

关于 moveEvent 的文档说:

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

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

在你的评论之后,另一个想法是重新实现:

void MainWindow::mouseMoveEvent(QMouseEvent *event)

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

【讨论】:

  • 嗯......这不是很无CPU! :) 可能会达到粘性,但频率很高。
【解决方案2】:

正如手册中明确指出的那样:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多