在Qt 5中似乎有些变化:如果你在调用QDrag::exec()时没有移动至少一个像素,就无法获得拖放或移动事件。尝试在可拖动图标示例的dropEvent中设置断点,然后单击一艘船并释放而不移动鼠标。这将生成一个“忽略”信号,没有任何拖放信号。
(这是在带有Qt 5.1的Kubuntu 13.10上进行的。)
当教授如何启动拖动操作时,文档建议您使用manhattanDistance()来确定鼠标是否移动足够,以真正符合“用户打算开始拖动”的条件。但你不必使用它;你可以在点击本身上启动QDrag。
有人知道解决这个问题的方法吗?还是说这个选择完全消失了? :-/
这会导致各种问题,而且它的问题会因平台而异。(暂时以Kubuntu 13.10和Qt 5.1为例)如果你按下鼠标按钮并拖出小部件,当你越过边界时,你会收到一个leaveEvent...然后在释放按钮时再收到另一个leaveEvent。如果你离开窗口并在屏幕上激活另一个应用程序中的窗口,然后在小部件内单击以重新激活Qt应用程序,你将获得两个连续的enterEvents。
对于每个鼠标事件重复此模式,并尝试牢牢掌握不变量......祝你好运!将这些固定到一个“知道”其状态并且不会崩溃的防弹应用程序中(特别是在面对狂点和alt-Tabbing时),有点难以实现。
如果你的程序进行分配并且有大量处理,而且不想在地毯下面做很多清理工作(例如,“哦,我正在响应进入而进行一些处理...但我刚刚没有离开就再次进入了。嗯,我猜那会发生!把当前的计算扔掉,重新开始...”),这是不好的。
过去我处理所有鼠标操作(甚至是简单的点击)都使用拖放。让操作涉及操作系统的拖放功能似乎会产生更强壮的体验。我只能推测这是因为测试人员实际上必须考虑诸如使用alt-Tab进行任务切换等问题,而不会导致多个放置操作或仅仅忘记已启动的操作。
但是,“嵌入到框架之上”的方面使得这个“一像素移动”要求不可能改变。我尝试通过设置计时器事件,然后伪造QMouseEvent来在拖动生效时将光标移动到新位置来绕过它。然而,我推测拖放是在平台级别上挂钩的,并且不会查询普通的Qt事件队列:src/plugins/platforms/xcb/qxcbdrag.cpp。
(这是在带有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。