【问题标题】:Getting a mouse drop event in Qt 5 if mouse doesn't move before mouse release如果鼠标在鼠标释放之前没有移动,则在 Qt 5 中获取鼠标放置事件
【发布时间】:2013-10-30 04:09:31
【问题描述】:

在 Qt 5 中似乎发生了一些变化:如果您从调用 QDrag::exec() 时所在的起点至少不移动一个像素,则无法获得放置或移动事件。尝试在Draggable Icons SampledropEvent 中放置一个断点,然后单击一条船并在不移动鼠标的情况下释放它。这会产生一个没有任何丢弃信号的“忽略”。

(这是在带有 Qt 5.1 的 Kubuntu 13.10 上。)

在教授如何开始拖动操作时,文档建议您可以使用manhattanDistance() 来确定鼠标是否移动到足以真正符合“打算开始拖动的用户”的条件。但是您不必使用它;您可以在点击本身上启动 QDrag。

任何人都知道在 drop 端有相同类型的选择的解决方法,还是该选择完全消失了? :-/


我为什么关心:长期以来,我一直在试图严格控制 GUI 应用程序(包括 Qt)中的鼠标行为时遇到挫折。似乎没有可信赖的状态转换图可以绘制不变量。这是一个纸牌屋,您可以通过以下简单测试轻松反驳:

virtual void enterEvent(QEvent * event) {
    Q_ASSERT(!_entered);
    _entered = true;
}

virtual void leaveEvent(QEvent * event) {
    Q_ASSERT(_entered);
    _entered = false;
}

这打破了各种方式,如何打破取决于平台。 (目前我将讨论 Kubuntu 13.10 和 Qt 5.1。) 如果您按下鼠标按钮并拖出小部件,当您越过边界时,您将收到一个 leaveEvent...然后释放按钮时另一个 leaveEvent 。如果您离开窗口并在屏幕上的窗口中激活另一个应用程序,然后在小部件内部单击以重新激活 Qt 应用程序,您将获得两个连续的 enterEvents。

对每个鼠标事件重复此模式,并尝试牢牢抓住不变量...祝你好运!将它们钉在一个“知道”它的状态并且不会崩溃(尤其是面对疯狂的点击和 alt-Tabbing)的防弹应用程序中是有点失败的原因。

如果您的程序进行分配并且处理繁重,并且不想在地毯下进行大量扫描(例如“哦,我正在为响应输入而进行一些处理……可是我又进不去了。嗯,我猜是这样的!扔掉当前的计算,重新开始……”)

过去我所做的是通过拖放来处理我的所有鼠标操作(甚至是简单的单击)。让操作系统拖放工具参与操作往往会产生更强大的体验。我只能推测这是因为测试人员实际上必须考虑使用 alt-Tab 进行任务切换等事情,而不是导致多次 drop 操作或忘记某个操作已经开始。

但是“在比框架更深的层次上进行烘焙”方面实际上使这个单像素移动的要求无法改变。我试图通过设置一个计时器事件来绕过它,然后在拖动生效后伪造一个 QMouseEvent 将光标撞到一个新位置。不过,我推测拖放是在平台级别挂钩的,并没有参考普通的Qt事件队列:src/plugins/platforms/xcb/qxcbdrag.cpp

【问题讨论】:

  • 由于似乎没有人知道解决方法,我在 Qt 跟踪器中opened an issue 对此进行了讨论。
  • 我遇到了同样的问题,我已经通过调用系统 api 方法来模拟鼠标移动开始拖动时解决它
  • @dvvrd 我打开了一个赏金。如果你能分享你的代码,那听起来是个不错的选择……!
  • 看来你的bug终于被注意到了,很快就会修复。所以现在我必须问你是否真的需要那个代码,而且我的解决方法是一个非常肮脏和丑陋的黑客,我觉得把它放在这里有点羞耻:) 这个想法只是在拖动开始时模拟一些鼠标事件(使用 QTest 或甚至原生系统 API)。

标签: qt drag-and-drop mouseevent qt5


【解决方案1】:

截至 2014 年 5 月 1 日,该问题已被 Qt 团队确认为错误:

https://bugreports.qt-project.org/browse/QTBUG-34331

似乎我在这里赏金最终引起了他们的注意,尽管它没有产生任何我可以接受的 SO 答案来最终确定问题。所以我正在写作并接受我自己的。干得好,我。 (?)抱歉没有更好的答案。 :-/

Qt5 更改还有另一个不幸的副作用,由“Dmitry Mordvinov”指出:

同样的问题。此外,直到拖动开始后的第一个鼠标事件才处理应用程序事件,这确实是一个讨厌的错误。例如,当您尝试使用触摸监视器拖动时,所有应用程序动画都会暂停或应用程序挂起。

@dvvrd 不得不解决它,但觉得解决方法太丑陋而无法分享。因此,如果您受到问题的影响,正确的做法是参与进来……并将您的声音添加到问题跟踪器中,以提高解决方案的优先级。

(或者更好:打补丁并提交补丁。毕竟是开源的......)

【讨论】:

    猜你喜欢
    • 2011-10-08
    • 2018-10-20
    • 2011-02-05
    • 2014-01-15
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2019-11-30
    相关资源
    最近更新 更多