0

QTでの描画のような落書きを実装するだけでなく、描画されたパスの一部を消去できる正しいアプローチは何でしょうか?

画像 (QImage) に楕円を点として追加することで描画が実装されている例を見てきましたが、私が理解している限り、描画された線を削除することはできませんか? 私が考えていることの 1 つは、QPainterPaths を実装することです。マウス ダウンで新しいパスを開始し、マウス移動でマウス位置のパスにポイントを追加し、マウス リリースでこのパスを終了します。描画イベントでは、QPainterPath の配列を調べて、それぞれを描画します。消去時には、配列内のすべての 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);
}

これらは 2 つの重要な機能です。mousePressEvent で新しいパスを開始し、現在のマウス位置に移動します。次に、パスを QGraphicsScene に追加して、mouseMoveEvent 関数で使用する QGraphicsPathItem へのポインターを取得します。

mouseMoveEvent 関数では、まず、現在消去中か描画中かを確認します。描画の場合、パスの最後のポイントから現在のマウス位置までの線を追加し、そのパスを QGraphicsScene に再度追加します。そうしないと、それらの新しい線が表示されません (もっと良い方法があるかもしれません。改善の余地があります)。それは描画のためです。削除する場合は、すべてのパスのリストを調べて、現在マウスの下にパスがあるかどうかを確認し、ある場合は削除します。

これは現在、単なるドラフトであり、さらに改善される予定です。

描画/落書きの素晴らしい例:

描画のいくつかの素晴らしい例

于 2016-08-04T21:21:29.303 に答える