5

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

(这是在带有 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 进行任务切换等事情,而不是导致多个 drop 操作或只是忘记一个操作已经开始。

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

4

1 回答 1

0

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

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

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

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

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

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

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

于 2014-05-08T12:15:08.890 回答