我更新了diagramcene示例以绘制窄线的法线.我在Arrow::paint
功能中添加了这一行:
painter->drawLine(line()); painter->drawLine(line().normalVector()); // this line was added //... //scene()->update(); //add this line make this paint function reloop infinitely
没有update
,正常线没有显示,如果我移动项目,它可以显示但不正确.有了update
,所有都是正确的绘画,但paint
功能是无限的reloop.我无法解释原因,请帮帮我!
// - 编辑:我添加了原始Arrow::paint
函数的代码:
void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if (myStartItem->collidesWithItem(myEndItem)) return; QPen myPen = pen(); myPen.setColor(myColor); qreal arrowSize = 20; painter->setPen(myPen); painter->setBrush(myColor); QLineF centerLine(myStartItem->pos(), myEndItem->pos()); QPolygonF endPolygon = myEndItem->polygon(); QPointF p1 = endPolygon.first() + myEndItem->pos(); QPointF p2; QPointF intersectPoint; QLineF polyLine; for (int i = 1; i < endPolygon.count(); ++i) { p2 = endPolygon.at(i) + myEndItem->pos(); polyLine = QLineF(p1, p2); QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint); if (intersectType == QLineF::BoundedIntersection) break; p1 = p2; } setLine(QLineF(intersectPoint, myStartItem->pos())); double angle = ::acos(line().dx() / line().length()); if (line().dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize, cos(angle + Pi / 3) * arrowSize); QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, cos(angle + Pi - Pi / 3) * arrowSize); arrowHead.clear(); arrowHead << line().p1() << arrowP1 << arrowP2; painter->drawLine(line()); painter->drawPolygon(arrowHead); if (isSelected()) { painter->setPen(QPen(myColor, 1, Qt::DashLine)); QLineF myLine = line(); myLine.translate(0, 4.0); painter->drawLine(myLine); myLine.translate(0,-8.0); painter->drawLine(myLine); } }
// - 更新:答案:
QRectF Arrow::boundingRect() const { qreal extra = (pen().width() + 20) / 2.0; QLineF myVLine = line().normalVector(); return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(), line().p2().y() - line().p1().y())) .normalized() .adjusted(-extra, -extra, extra, extra) .united(QRectF(myVLine.p1(), QSizeF(myVLine.p2().x() - myVLine.p1().x(), myVLine.p2().y() - myVLine.p1().y()))); }
Jeremy Fries.. 6
添加对update()的调用导致paint()方法被反复调用的原因正如Ari0nhh在他的注释中所说的那样 - 具体来说,update()方法导致另一个调用paint()被调度,并且下一次调用paint()会调用update(),依此类推.当然,解决这个问题的方法是不要在paint()中调用update().
但是,您真正的问题是导致您觉得需要首先调用update()的方法:您添加的行未正确显示.这样做的原因是你添加的代码是"作弊" - 具体来说,它试图在Arrow对象承诺它只能在内部绘制的区域之外绘制.因此,显示器无法正确更新.
Arrow类如何告诉Qt场景它将绘制的位置?通过重写boundingRect()和shape()虚方法.你会注意到,Arrow类已经覆盖了这两种方法,以说明它在行的一端添加了arrowHead; 为了正确绘制第二行,您还需要在返回的边界矩形和形状值中包含额外的线条范围.
添加对update()的调用导致paint()方法被反复调用的原因正如Ari0nhh在他的注释中所说的那样 - 具体来说,update()方法导致另一个调用paint()被调度,并且下一次调用paint()会调用update(),依此类推.当然,解决这个问题的方法是不要在paint()中调用update().
但是,您真正的问题是导致您觉得需要首先调用update()的方法:您添加的行未正确显示.这样做的原因是你添加的代码是"作弊" - 具体来说,它试图在Arrow对象承诺它只能在内部绘制的区域之外绘制.因此,显示器无法正确更新.
Arrow类如何告诉Qt场景它将绘制的位置?通过重写boundingRect()和shape()虚方法.你会注意到,Arrow类已经覆盖了这两种方法,以说明它在行的一端添加了arrowHead; 为了正确绘制第二行,您还需要在返回的边界矩形和形状值中包含额外的线条范围.