我在使用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);
此代码执行以下操作:
编辑开始
根据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行)。