移动后跟随QWidget

时间:2013-06-26 13:34:07

标签: qt mouseevent mousemove qwidget qmainwindow

我正在尝试让QWidget跟随另一个,而这正在移动。

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

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

如何让{em>追随者“坚持”QMainWindow?我喜欢它实际上似乎粘在窗户上,而我拖着它!

任何提示?

干杯!

2 个答案:

答案 0 :(得分:0)

文档说关于moveEvent:

  

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

所以也许更好的想法是定期检查(例如使用 QTimer )mainWindow的位置,如果更改则移动关注者。

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

void MainWindow::mouseMoveEvent(QMouseEvent *event)

使用自定义窗口小部件(即新窗体或使用Qt :: FramelessWindowHint)而不使用系统栏,拖动将通过重新实现的自定义栏完成,在这种情况下,您可以将mainWindow和关注者一起移动。

答案 1 :(得分:0)

手册中明确指出:

小部件收到此事件后,它已经在新位置

因此,如果您等待moveEvent触发,则在完成拖动主窗口之前不会发生任何事情。
如果您可以容忍跟随者窗口在伙伴周围被拖动时坐在那里的视线,那么它将可以正常工作。

1990年左右的感觉绝非偶然。 Windows怪异地在屏幕上移动内容的方式确实是由于传统策略可以追溯到尝试在屏幕上复制位图的次数过多而使膝部屈膝的时代。

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

无论如何,从Windows程序中可以看到,您将收到WM_ENTERSIZEMOVE,然后收到未知数​​量的WM_MOVING(您可能希望对其进行过滤,以避免过于频繁地移动关注者窗口),直到您收到WM_LEAVESIZEMOVE的最终通知。
您可以重载方便的WinEvent方法来监视这些本机消息。 WM_LEAVESIZEMOVE不是强制性的,您也可以等待标准Qt moveEvent

我强烈建议您不要在Google上找到各种黑客。窥视事件队列并检测例如单击窗口的系统栏,监视原始鼠标事件等。 尽管您最终可能会成功,但至少在简单的情况下,尝试重写窗口管理器的一点点,尤其是像Win32那样糟糕而过时的窗口管理器,将坚定而反复地提出问题。

无论如何,在我看来,跳过所有这些箍只是为了获得较小的外观和感觉改善,绝对不值得麻烦。