0

我需要用 Qt 绘制曲线:用户单击 QGraphicsScene(通过 QGraphicsView),并在用户单击的点之间绘制直线。当用户画完直线(通过点击右键),这组线变成了一条曲线。

为此,我需要使用该QPainterPath::cubicTo(...)方法并使用QGraphicsScene::addPath(...).

问题是我不知道如何计算传递给cubicTo(...).

例如,在下图中,用户通过单击点 AB 和 C 绘制了两条灰线。当她单击右键时,我想使用 绘制红线cubicTo(...)

预期的线条和曲线

我当前的代码仅绘制灰线,因为我已将 、 和 值设置c1为用户单击的点位置:c2d1d2

void Visuel::mousePressEvent(QMouseEvent *event)
{
    int x = ((float)event->pos().x()/(float)this->rect().width())*(float)scene()->sceneRect().width();
    int y = ((float)event->pos().y()/(float)this->rect().height())*(float)scene()->sceneRect().height();
    qDebug() << x << y;

    if(event->button() == Qt::LeftButton)
    {
        path->cubicTo(x,y,x,y,x,y);
    }
    if(event->button() == Qt::RightButton)
    {
        if(path == NULL)
        {
            path = new QPainterPath();
            path->moveTo(x,y);

        }
        else
        {

            path->cubicTo(x,y,x,y,x,y);
            scene()->addPath(*path,QPen(QColor(79, 106, 25)));
            path = NULL;
        }
    }
}
4

1 回答 1

1

显然控制点 c1、c2、d1、d2 只是图片中 B 点的坐标。在更一般的情况下,点 C 位于 AB 线上,点 D 位于 BC 线上。

在 Qt 代码中可以这样写: Visuel 类应该具有以下属性:

QPoint A, B, C;
unsigned int count;

应该在 Visuel 的构造函数中初始化。

void Visuel::Visuel()
{
    count = 0;
    // Initialize other stuff as well
}

然后我们要重载 QGraphicsScene::mousePressEvent() 来检测用户的鼠标事件:

void Visuel::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    /* Ignore everything else except left button's press */
    if (event->type() != QEvent::GraphicsSceneMousePress ||
        event->button() != Qt::LeftButton) {
        return;
    }
    switch (count) {
    case 0:
        A = event->scenePos();
        break;
    case 1: {
        B = event->scenePos();

        /* Draw AB line */
        QPainterPath path(A);
        path.lineTo(B);
        scene()->addPath(path, Qt::grey);
        }
        break;
    case 2: {
        C = event->scenePos();

        /* Draw BC line */
        QPainterPath path(B);
        path.lineTo(C);
        scene()->addPath(path, Qt::grey);

        /* Draw ABBC cubic Bezier curve */
        QPainterPath path2(A);
        path2.cubicTo(B, B, C);
        scene()->addPath(path2, Qt::red);
        }
        break;
    default:
        break;
    }
    if (count >= 2) {
        count = 0;
    } else {
        count++;
    }
}
于 2012-10-22T12:33:51.623 回答