0

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

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

这是一些有效的方法还是 QPaths 无法实现的?

有没有更好、更聪明的方法来做到这一点?

4

1 回答 1

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,否则它不会显示这些新线(也许有更好的方法,我愿意改进),这就是绘画。如果我们要删除,我会浏览所有路径的列表并检查当前是否有任何路径在鼠标下,如果是,则将其删除。

目前这只是一个草案,未来会有更多改进。

一些很棒的绘图/涂鸦示例:

一些很棒的绘图示例

于 2016-08-04T21:21:29.303 回答