如何实现涂鸦绘图,有可能擦除QT中的路径?

时间:2016-08-03 19:24:59

标签: c++ qt qpainterpath

在QT中实现涂鸦的正确方法是什么,但也能够删除一些绘制的路径?

我已经看过一些例子,其中绘图是通过添加椭圆作为图像点(QImage)来实现的,但据我所知,你将无法删除任何绘制的线条?我一直在考虑的一件事是实现QPainterPaths。在鼠标按下时,启动一个新路径,在鼠标移动时将点添加到鼠标位置的路径,并在鼠标释放时完成此路径。在绘制事件中,我将浏览一系列QPainterPaths并绘制每个QPainterPaths。在擦除时,我将遍历数组中的每个QPainterPath并检查是否有任何点发生碰撞,如果是,则从数组中删除整个路径,有效地擦除它。

这是一种有效的方法还是用QPath无法实现的?

有更好,更聪明的方法吗?

1 个答案:

答案 0 :(得分:0)

这似乎确实是有效的,或者至少是一种有效的方法,即使我的问题有点宽泛,最终有人会发现答案有用:

/*
 * QList<QGraphicsPathItem *> mList;
 * bool mErase;
 * QPainterPath * mCurrentPath;
 * QPainterPathStroker mStroker;
 */

void ScribbleArea::mousePressEvent ( QGraphicsSceneMouseEvent* event)
{
    if(!mErase)
    {
        mCurrentPath = new QPainterPath();
        mCurrentPath->moveTo(event->lastScenePos());
        mList.append(addPath(mStroker.createStroke(*mCurrentPath), QPen(Qt::red), QBrush(Qt::red)));
    }
    QGraphicsScene::mousePressEvent(event);
}

void ScribbleArea::mouseMoveEvent ( QGraphicsSceneMouseEvent* event)
{ 
      if(!mErase)
      {
          mCurrentPath->lineTo(event->lastScenePos());
          mList[mList.count()-1]->setPath(mStroker.createStroke(*mCurrentPath));
      }
      else
      {
          for(int i=0; i < mList.count(); i++)
          {
              if(mList[i]->isUnderMouse())
              {
                  removeItem(mList[i]);
                  delete mList[i];
                  mList.removeAt(i);
              } 
          }
      }    
      QGraphicsScene::mouseMoveEvent(event);
}

这是两个关键函数,在mousePressEvent上我启动一个新路径并将其移动到当前鼠标位置,然后,我添加QGraphicsScene的路径以获取指向QGraphicsPathItem的指针,我将在mouseMoveEvent函数中使用它。

在mouseMoveEvent函数中,我首先检查我们当前是否正在擦除或绘图。在绘制的情况下,我从路径最后一点到当前鼠标位置添加一行,并再次将路径添加到QGraphicsScene,否则它不会显示那些新行(可能有更好的方法,我打开改进),那就是绘画。 如果我们要删除,我会浏览所有路径的列表并检查鼠标下是否有任何路径,如果是,则将其删除。

目前这只是草案,还有更多改进。

绘画/涂鸦的一些很棒的例子:

Some awesome example of the drawing