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

时间:2013-10-21 15:17:11

标签: qt drag-and-drop mouseevent qt5

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

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

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

任何人都知道有一种解决方法可以在丢弃方面做出同样的选择,还是完全没有选择? : - /


为什么我关心:我一直很沮丧,试图严格控制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等进行任务切换等事情,并且不会导致多次丢弃操作或只是忘记操作已经开始。

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

  

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

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

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