【发布时间】:2015-08-20 13:02:32
【问题描述】:
我目前正在尝试实现贝塞尔钢笔工具。事件进程如下:
- 点击点(QGraphicsItem),点击开始移动
- 在 QGraphicsScene mouseMoveEvent 中,阻止点的移动(带有布尔标志),直到从 point.pos() 到 event.scenePos() 的距离达到阈值。当发生这种情况时,取消选择和 mouseRelease 点,添加一个节点 (QGraphicsItem) - 选择它并给它 mousePress 状态(加上取消设置布尔标志)
- 之后用户可以移动节点,然后松开鼠标。
(节点是点的子项。)
我尝试在场景的 mouseMoveEvent 中执行此操作(我有一个条件分支知道何时执行此操作):
point.setSelected(False)
point.ungrabMouse()
node.setPos(event.scenePos()-point.pos()) # positioning relative to point since it’s a childItem()
node.grabMouse()
event.accept()
但是在这样做之后,节点只是在我释放鼠标后才获得mouseMoveEvent......(我在控制台中打印它们,节点本身没有移动。)
所以我想,也许场景需要在“释放焦点”之前吃掉一个 mouseReleaseEvent。发现一篇与here主题相切的文章。
然后我没有使用 ungrabMouse()/grabMouse(),而是尝试了这个:
mouseRelease = QEvent(QEvent.MouseButtonRelease)
self.sendEvent(point, mouseRelease)
node.setPos(event.scenePos()-point.pos()) # positioning relative to point since it’s a childItem()
mousePress = QEvent(QEvent.MouseButtonPress)
self.sendEvent(node, mousePress)
现在当我达到距离阈值时,我可以看到只有点被选中(很好)但是当我进一步移动时,点和节点都被选中并移动了……我希望由于我取消选择并释放(父)点,它不会继续移动。
我链接到的文章确实做了一些不同的事情,但它说“事实证明,我们必须模拟鼠标释放事件来清除 Qt 的内部状态。”这可能与当前情况有关,但是我不知道可能需要采取哪些额外步骤才能“清除 Qt 的内部状态”……所以我希望 QGraphics 爱好者可以参与进来并帮助我解决这个问题。
感谢您在这里查看。
【问题讨论】:
-
您的小部件上是否启用了鼠标跟踪?
QWidget::setMouseTracking(true); -
@JohannesMunk 嗨 Johannes,也许我的帖子不清楚:我愿意做的基本上是这样的:-单击点,单击时开始移动-在 QGraphicsScene mouseMoveEvent 中,当从点到事件的距离.pos() 达到阈值,取消选择并释放点,生成节点 - 选择它并赋予它 mousePress 状态 - 之后用户可以继续移动节点,然后释放鼠标。无需使用 setMouseTracking(True) 这一切是否可行?我想基本上将小部件设置为 mousePress 状态,这样我就不必总是跟踪鼠标。谢谢
-
为什么要避免mouseTracking?
-
@JohannesMunk 因为它是一个附加的、可选的功能层,我认为可以通过释放和按下来实现,不是吗?
-
我怀疑你能做到这一点。我从来没有遇到过mouseTracking 的问题。澄清一下:一切正常,如果你启用它?
标签: qt qgraphicsitem qgraphicsscene qmouseevent