首页 文章

如果鼠标在鼠标释放前未移动,则在Qt 5中获取鼠标停放事件

提问于
浏览
5

在Qt 5中似乎有些变化:你可以从调用 QDrag::exec() 时的起点移动至少一个像素 . 尝试在Draggable Icons SampledropEvent 中放置断点,然后单击一条船并在不移动鼠标的情况下释放它 . 这会产生"ignore"而没有任何掉落信号 .

(这是在Qub 5.1的Kubuntu 13.10上 . )

在教授如何开始拖动操作时,文档建议您可以使用 manhattanDistance() 来确定鼠标是否已经移动到足以真正符合"the user intending to start a drag"的条件 . 但你不必使用它;您可以在点击本身上启动QDrag .

任何人都知道有一种解决方法可以在丢弃方面做出同样的选择,或者这种选择是否完全消失了? : - /


Why I care: 我've long had frustrations trying to get a tight control on mouse behavior in GUI apps—Qt included. There seems to be no trustworthy state transition diagram you can draw of the invariants. It'是一个纸牌屋,你可以通过简单的测试很容易地反驳:

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 . )如果你按下鼠标按钮并拖出小部件,你将获得两个连续的enterEvents .

为每个鼠标事件重复此模式,并试着 grab 不变量...祝你好运!将这些内容钉入一个防弹应用程序,“知道”它的状态并且不会崩溃(特别是面对狂野点击和alt-Tabbing)是一个失败的原因 .

这不是想在地毯下做很多扫地(例如"Oh, I was doing some processing in response to being entered... but I just got entered again without a leave. Hm, I guess that happens! Throw the current calculations away and start again...")

在过去,我所做的是通过拖放操作来处理所有鼠标操作(甚至是简单的点击) . 获得操作中涉及的操作系统拖放设施往往会产生更强大的体验 . 我只能假设这是因为测试人员实际上不得不考虑使用alt-Tab等进行任务切换之类的事情,并且不会导致多次丢弃操作或只是忘记操作已经启动 .

但是"baked in at a level deeper than the framework"方面实际上使得这个单像素移动要求无法改变 . 我试图通过设置一个计时器事件来破解它,然后伪造一个QMouseEvent,一旦拖动生效,就将光标碰到一个新位置 . 但是,我猜测拖放是在平台级别挂钩,并不参考普通的Qt事件队列:src/plugins/platforms/xcb/qxcbdrag.cpp

1 回答

  • 0

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

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

    看来我在这里的报道最终引起了他们的注意,虽然它没有产生任何我可以接受的SO答案来最终确定问题 . 所以我写作并接受我自己的 . 干得好,我 . (?)抱歉没有更好的答案 . : - /

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

    这里的问题相同 . 另外,在拖动开始之后,第一个鼠标事件才会处理应用程序事件,这是非常讨厌的错误 . 例如,当您尝试使用触摸显示器拖动时,所有应用程序动画在此时暂停或应用程序挂起 .

    @dvvrd不得不解决它,但觉得解决方法太难看了,无法分享 . 所以,如果你受到这个问题的影响,那么正确的做法就是权衡...并将你的声音添加到问题跟踪器中,或许可以提高解决方案的优先级 .

    (或者甚至更好:修补它并提交补丁 . 毕竟,这是开源的......)

相关问题