【问题标题】:Smooth line in QGraphicsScene with Qt使用 Qt 在 QGraphicsScene 中平滑线
【发布时间】:2012-10-19 18:35:20
【问题描述】:

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

为此,我需要使用QPainterPath::cubicTo(...) 方法并使用QGraphicsScene::addPath(...) 将路径添加到QGraphicsScene。

问题是我不知道如何计算传递给cubicTo(...) 的参数值。

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

我当前的代码只画了灰线,因为我已将c1c2d1d2 值设置为用户点击的点位置:

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;
        }
    }
}

【问题讨论】:

    标签: qt curve-fitting qgraphicsscene qpainter mousepress


    【解决方案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++;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 2012-03-17
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多