QGraphicsItem :: shape()与点击次数

时间:2016-06-23 19:59:42

标签: qt qt5

我在使用Qt(5.6)时遇到了一些问题。

我正在使用 QGraphicsItemGroup 来表示 QGraphicsScene 上的弧线(Bezier曲线,从左到右然后旋转)。 我希望用户在点击或靠近它时可以选择此弧。我们的想法是让弧线本身可以点击,以及弧线周围的小条带。

为了做到这一点,我使用 QGraphicsItem :: shape()来返回与我想要点击的区域相对应的形状。

上下文

生成形状的代码如下, arrowPath 是弧形路径本身(下面的解释):

QPainterPath arrowPath = ((QGraphicsPathItem*)this->arrowBody)->path();

path.moveTo(0, this->middleBarLength/2);
path.lineTo(0, -this->middleBarLength/2);

arrowPath.translate(0, -this->middleBarLength/2);
path.connectPath(arrowPath);

path.lineTo(arrowPath.boundingRect().width(), this->middleBarLength/2);

arrowPath.translate(0, this->middleBarLength);
arrowPath = arrowPath.toReversed();
path.connectPath(arrowPath);

path.closeSubpath();

QTransform t;
t.rotate(-sceneAngle);
this->boundingShape = t.map(path);

此代码执行以下操作:

  • 绘制一条垂直线(自下而上),其大小 middleBarLength (条带宽度)垂直居中于弧线上,
  • 将弧形路径转换为最新位置并链接它,
  • 绘制另一条垂直线(自上而下),
  • 反转圆弧路径,将其转换为最新位置并将其链接,
  • 关闭路径,
  • 旋转形状以匹配圆弧旋转。

编辑开始

根据Kuba Ober的建议,我将上面的代码更改为以下代码,这更加简单:

QPainterPath arrowPath = ((QGraphicsPathItem*)this->arrowBody)->path();

QPen pen(QBrush(Qt::SolidPattern), this->middleBarLength/2);
QPainterPathStroker stroker(pen);

path = stroker.createStroke(arrowPath);

QTransform t;
t.rotate(-sceneAngle);
this->boundingShape = t.map(path);

但这并不能解决问题......

编辑结束

shape()函数只返回 boundingShape 对象,该对象会根据弧上的任何更改进行更新。

boundingShape 对象也用于其他目的:显示一个虚线框,表示选中了弧(覆盖默认选择框)。当我显示选择框时,此代码会生成正确的形状。

问题

问题发生如下:虽然外观部分似乎观察到形状(凸起侧面上的形状点击不选择它,不像 boundingRect()),它是不适合内部形状:在形状外部,在凹面上,在弧的两个点之间的位置选择它。我不确定我的解释是否清楚,我希望你能明白我的意思。

问题是我可以有不同的弧,具有不同的曲率半径,但具有相同的原点/目标。全部处于相同的Z堆叠顺序,可以选择不正确的弧。如果不对我的代码进行重大修改,我无法定义不同的Z位置。

我尝试手动解决,并设法通过添加特定的点击检查来实现:

mousePressEvent(QGraphicsSceneMouseEvent* ev)
{
    if ( ! this->boundingShape.contains(ev->pos()) )
        ev->ignore();
}

但是我不明白为什么我必须这样做,这可能是有害的,因为我不能实现鼠标释放,双击和移动功能而不会破坏这种行为。此外,通过添加此代码,它可以在鼠标释放时使用,而不是鼠标按下。

所以如果有人对正在发生的事情有所暗示,我会非常感激。

其他信息

如果需要,可在函数 rebuildBoundingShape()(第341行)here中获取该类的完整代码。这是 else else (第401行)。

0 个答案:

没有答案