使用 mouseMoveEvent 约束 QGraphicsItem 移动

Posted

技术标签:

【中文标题】使用 mouseMoveEvent 约束 QGraphicsItem 移动【英文标题】:Constrain QGraphicsItem movement with mouseMoveEvent 【发布时间】:2016-10-24 14:56:03 【问题描述】:

我正在尝试正确限制 QGraphicsItem(特别是 QGraphicsRectItem)的移动,而不更改本机行为以用作 X 轴上的滚动条。

我尝试覆盖 mouseMoveEvent 函数,但随后我需要重新编写矩形在 X 和 Y 方向上的行为。充其量,我可以让矩形用鼠标捕捉到一个位置。 (此处矩形将捕捉,因此鼠标将其保持在中点):

void SegmentItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

  setY(0);
  setX(event->scenePos().x() - boundingRect().width()/2);

我现在正在查看itemChange,正如here 所描述的那样,但它看起来有点笨拙且不完全优雅。 编辑:这应该可以工作,但我目前无法强制它工作。

有没有办法只限制 y 轴的运动? (我还需要为滚动条创建终点站,但稍后。)

【问题讨论】:

链接的 itemChange 解决方案是解决方案,而且确实非常优雅 很酷,但目前似乎没有任何限制。我在Class Reference Page 上阅读了“默认实现什么都不做,并返回值。” 你知道我需要改变什么吗? 【参考方案1】:

我修改了itemChange 类参考页面中的代码,并对其进行了增强,因此我的QGraphicsRectItem 的所有四个角都将保留在QGraphicsScene 内:

QVariant SegmentItem::itemChange(GraphicsItemChange change, const QVariant &value)
 
     if (change == ItemPositionChange && scene()) 
         // value is the new position.
         QPointF newPos = value.toPointF();
         QRectF rect = scene()->sceneRect();
         rect.setWidth(rect.width() - boundingRect().width());
         rect.setHeight(0);
         if (!rect.contains(newPos)) 
             // Keep the item inside the scene rect.
             newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
             newPos.setY(2);
             return newPos;
         
     
     return QGraphicsItem::itemChange(change, value);
 

【讨论】:

【参考方案2】:

要回答关于将运动限制在一个方向的问题的另一部分...使用与上述答案中相同的 itemChange 结构。您需要做的唯一额外的事情是在返回之前将您的项目的当前 X 或 Y 坐标转移到新位置。此行允许 Y 跟踪鼠标,但保持 X 不变(即移动被限制为垂直):

newPos.setX (this->pos().x());

同样,允许 X 跟踪鼠标,但保持 Y 不变(即移动被限制为水平):

newPos.setY (this->pos().y());

使用 ItemPositionChange 通知,项目的当前位置尚未更改,因此您可以在返回新值之前以任何方式操作新位置。

【讨论】:

酷,这也让事情变得更容易!

以上是关于使用 mouseMoveEvent 约束 QGraphicsItem 移动的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Qt 防止 QCursor::setPos() 上的 mouseMoveEvent?

QT5 mouseMoveEvent事件

在 Qt 中获取 MouseMoveEvents

QGraphicsView 中的 MouseMoveEvent

工具提示停止 mouseMoveEvent

自定义 QGraphicsRectItem 无法接收 mouseMoveEvent