0

qt で画像を描画するには、qpainter が使用されることがわかっています。最近、私は drawLine() 関数を使用して、ユーザーが落書きしているものを何でも描画しました。これは、lastPoint と currentPoint を mouseMoveEvent から drawLine() を実装するカスタム関数に渡すことによって行われました。以下に示すように、そのカスタム関数の引数を渡しました。

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
qDebug() << event->pos();
   if ((event->buttons() & Qt::LeftButton) && scribbling) {
    pixelList.append(event->pos());
    drawLineTo(event->pos());
    lastPoint = event->pos();
   }
}

qDebug() の助けを借りて、描画中に一部のピクセルが欠落していることに気付きましたが、描画は正確です。qt-painting のソースを調べたところ、drawLine() が drawLines() を呼び出していて、qpainterPath を使用して画像に図形を描画していたことがわかりました。

私の質問は、これらの「見逃された」ピクセルを追跡する方法や、描画されたすべてのピクセルを見つける方法はありますか?

ありがとう!

void myPaint::drawLineTo(const QPoint &endPoint) {    
QPainter painter(image); //image is initialized in the constructor of myPaint
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
painter.drawLine(lastPoint, endPoint);
modified = true;
lastPoint = endPoint; //at the mousePressEvent, the event->pos() will be stored as
                      // lastPoint 
update();
}
4

1 に答える 1

2

まず、を描画しないでくださいmouseEvent()。実際にマウスイベントを処理するには、できるだけ早く実行する必要があります。また、Qtソースを確認することはお勧めできません。混乱を招く可能性があります。むしろ、Qtがあなたに仕事を与えると仮定し、最初に「私が間違っていることは何ですか?」と答えてみてください。私が言ったように、マウスイベントでの描画は間違いなく間違っています。

あなたの説明は本当に主観的です、多分あなたの出力のイメージはより良いです。ペンをエミュレートしようとしていますか(ウィンドウペイントのように)?この場合、マウスボタンを押す必要がありますか?それはあなたの変数の目的scribblingですか?

もっとある。ドキュメントに従って、QMouseEvent :: buttons()は、マウス移動イベントのすべてのボタンの組み合わせを常に返します。これは理にかなっています:マウスの動きはボタンとは無関係です。その意味は

if ((event->buttons() & Qt::LeftButton)

常に真実になります。

左ボタンが押されたときにマウスのパスを描画したいとします。次に、次のようなものを使用します:

void myPaint::mousePressEvent(QMouseEvent *event){
     scribbling = true;
     pixelList.clear();
}

void myPaint::mouseReleaseEvent(QMouseEvent *event){
     scribbling = false;
}

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
  if ( scribbling) {
    pixelList.append(event->pos());
  }
}

void myPaint::paintEvent(){
  QPainter painter(this)
  //some painting here
  if ( scribbling) {
     painter.setRenderHint(QPainter::Antialiasing);
     painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
    // here draw your path
    // for example if your path can be made of lines, 
    // or you just put the points if they are close from each other
  }

  //other painting here
}

このすべての後で適切なレンダリングができない場合は、float精度(遅い)を使用してみてください。つまり、QMouseEvent::posF()の代わりに使用してくださいQMouseEvent::pos()

編集:
「drawLineに引数として送信する任意の2つのピクセル間のすべてのサブピクセルを計算する方法があるかどうかを知りたい」
はい、あります。なぜそんなことをする必要があるのか​​わかりませんが、本当に簡単です。線は次の方程式で特徴付けることができます

   y = ax + b

線の両方の端点はこの方程式p0 = (x0, y0)を満たしているので、p1 = (x1, y1)簡単に見つけることができます。今、あなたがする必要があるのは、あなたが望むピクセルの量(例えば1)だけからに増分し、保存するたびに対応する値を計算することです。abx0x1ypoint(x,y)

したがって、保存されているすべてのポイントを確認しpixelList、2つの連続するポイントに対してこのプロセスを繰り返します。

于 2012-03-13T12:54:10.810 に答える