当前位置:  开发笔记 > 编程语言 > 正文

paint函数无限地重新循环

如何解决《paint函数无限地重新循环》经验,为你挑选了1个好方法。

我更新了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; 为了正确绘制第二行,您还需要在返回的边界矩形和形状值中包含额外的线条范围.



1> Jeremy Fries..:

添加对update()的调用导致paint()方法被反复调用的原因正如Ari0nhh在他的注释中所说的那样 - 具体来说,update()方法导致另一个调用paint()被调度,并且下一次调用paint()会调用update(),依此类推.当然,解决这个问题的方法是不要在paint()中调用update().

但是,您真正的问题是导致您觉得需要首先调用update()的方法:您添加的行未正确显示.这样做的原因是你添加的代码是"作弊" - 具体来说,它试图在Arrow对象承诺它只能在内部绘制的区域之外绘制.因此,显示器无法正确更新.

Arrow类如何告诉Qt场景它将绘制的位置?通过重写boundingRect()和shape()虚方法.你会注意到,Arrow类已经覆盖了这两种方法,以说明它在行的一端添加了arrowHead; 为了正确绘制第二行,您还需要在返回的边界矩形和形状值中包含额外的线条范围.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有