Как реализовать рисование каракулей с возможностью стирания путей в QT?

Каков был бы правильный подход для реализации каракулей, таких как рисование в QT, но также и возможность стереть некоторые нарисованные пути?

Я видел несколько примеров, где рисование реализовано путем добавления эллипсов в виде точек к изображениям (QImage), но, насколько я понимаю, вы не сможете удалить ни одну из нарисованных линий? Одна вещь, о которой я думал, это реализовать QPainterPaths. Нажав кнопку мыши, начните новый путь, при перемещении мыши добавьте точки к пути в месте расположения мыши, а после отпускания мыши завершите этот путь. На событии draw я бы прошел массив QPainterPaths и нарисовал каждый из них. При удалении я бы проходил через каждый QPainterPath в массиве и проверял, сталкивается ли какая-либо точка, если да, удаляет весь путь из массива, эффективно стирая его.

Это какой-то верный подход или что-то, чего нельзя достичь с помощью QPath?

Есть ли лучший, умный способ сделать это?

1 ответ

Решение

Похоже, что это действительно правильный или, по крайней мере, рабочий подход, хотя мой вопрос немного широк, в конце концов кто-то найдет ответ полезным:

/*
 * 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, в противном случае он не будет отображать эти новые линии (возможно, есть лучший способ, я открыт для улучшений), это все для рисования. В случае, если мы удаляем, я просматриваю список всех путей и проверяю, находится ли какой-либо из путей в данный момент под мышью, если да, удаляю его.

В настоящее время это всего лишь черновик, впереди еще много улучшений.

Несколько удивительных примеров рисования / писанины:

Несколько удивительный пример рисунка

Другие вопросы по тегам