【问题标题】:Qt transfer mouse move events to new windowQt 将鼠标移动事件转移到新窗口
【发布时间】:2019-11-18 13:12:12
【问题描述】:

我正在处理 QTabBar 上的鼠标事件(通过事件过滤器),以检测用户何时单击并拖动选项卡以将其撕下。发生这种情况时,我从 QTabWidget 中删除当前小部件并创建一个新的顶级小部件,并将其添加到其中,以便它分离和浮动,就像您在 Chrome 中撕下一个选项卡时一样。这个新的浮动窗口是我制作的一个自定义无框架小部件,它有一个自定义标题栏,我可以在上面处理鼠标事件,以允许用户在桌面上拖动窗口。

我遇到的问题是,当您单击并拖动选项卡以将其拉出并创建新的顶级窗口时,我似乎无法让应用程序在没有用户单击的情况下继续拖动新窗口并拖动我的标题栏。我希望原始的拖动动作只是转移到新的小部件,以便用户可以继续拖动它,直到他释放鼠标按钮。

我尝试创建一个“假”QMouseEvent 以传递给我的标题栏(通过调用 QCoreApplication::sendEvent(object, event) 让它认为它已被点击,但它不会接收任何鼠标移动事件,除非你 实际上 点击它。我对其他想法持开放态度。

更新:我添加了一些调试语句,看起来一旦我分离选项卡并创建新的浮动窗口,QMainWindow 会继续接收鼠标移动事件,直到我释放鼠标按钮。我会尝试添加一些代码来将这些鼠标事件转发到新的浮动窗口,但这感觉有点 hacky。

更正: QMainWindow 没有接收到鼠标移动事件,一个名为 "MainWindowWindow" 的对象是,这是一个 QWidgetWindow,我猜它是一个私有类型,用于管理顶级窗口?

【问题讨论】:

标签: c++ qt qwidget


【解决方案1】:

好的,我得到了它的工作,但我不喜欢它。正如我在更正中所说,一旦标签分离,QWidgetWindow 就会开始接收鼠标移动事件。这是不通过 API 公开的私有类型。

我最终做的是在应用程序上安装一个事件过滤器,并在继承自 QWidgetWindow 的对象上查找鼠标事件。然后我直接调用我添加到浮动窗口类的新的drag()endDrag() 方法。在我的 eventFilter 方法中,它看起来像这样。

if (watched->inherits("QWidgetWindow"))
{
  if (floater) // <- the floating window that was recently detached
  {
    if (event->type() == QEvent::MouseMove)
    {
      floater->drag(QCursor::pos()); // <-- Pass global cursor pos
    }
    else if (event->type() == QEvent::MouseRelease)
    {
      floater->endDrag();
      floater = nullptr;
    }
  }
}

就像我说的,如果感觉很脏,因为我 A) 正在检查我不应该知道的私有类型上的事件,并且 B) 告诉另一个窗口在它有代码自己执行此操作时拖动。但它有效,而且我已经花了足够的时间来解决这个问题。如果有人有更优雅的解决方案,我很高兴听到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2011-03-06
    相关资源
    最近更新 更多