15

QT 4.5でペイントプログラムを実行しようとしているので、キャンバスにQGraphicsViewを使用し、描画されたアイテムを保存するためにQGraphicsSceneを使用しています。いくつかの理由で、自分の派生QGraphicsViewでQPainterコンテキストを取得できませんでした

class DrawingCanvas : public QGraphicsView
{ 
  DrawingCanvas::DrawingCanvas(QWidget * parent);

 ...
};

DrawingCanvas::DrawingCanvas(QWidget * parent = 0) : QGraphicsView(parent) 
{
  ....
}

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo)
{
  // Result in painter not active
  QPainter(this);
  ...
}

ただし、DrawingCanvasをQWidgetの子に変更すると、機能します。QGraphicsViewがQAbstractScrollArea、QFrame、QWidgetの順に派生していることを考えると、コードが機能することを期待しています。

だから私は質問が次のとおりだと思います:

1)QGraphicsViewでpaintEventを使用してアクティブなQPainterを取得できないのはなぜですか?2)入手できる可能性はありますか?

前もって感謝します!

4

3 に答える 3

17

これがどういうわけか可能かどうかまだ誰かが疑問に思っているなら、答えはイエスです。

短縮版

void DrawingCanvas::paintEvent(QPaintEvent& paintEventInfo)
{
    // Result in painter active
    QPainter(viewport());
    ...
}

ロングバージョン

QGraphicsSceneはそれ自体ではペイントしませんが、代わりに、指定したビューポートウィジェットまたはデフォルトでQWidgetでペイントします。

代わりにビューポートにペイントすることで、シーンではなくビューに位置合わせされるオーバーレイペイントを実現できます。または、QGlWidgetとそのpaintOverlayGl()を使用することもできます。

また、viewportUpdateMode(QGraphicsView :: FullViewportUpdate)を設定することを忘れないでください。そうしないと、レンダリングアーティファクトが発生します。ビュー全体を毎回更新するよりも、アーティファクトを回避するための賢い方法があるかもしれませんが、パフォーマンスの問題が発生するまで、それを休ませます。

于 2010-02-02T07:48:47.980 に答える
4

そうです、しばらく髪を抜いた後は無理そうなので、これが私の解決策です。描画するものはすべてQGraphicsSceneに追加する必要があります。したがって、そこから独自の実装を導き出します。

最も簡単な方法は、描画する線や長方形などの一時的なQGraphicsItemポインタを定義することです。

それに応じて、仮想mousePressed()、mouseMove()、およびmouseRelease()イベントをオーバーライドします。mousePressed()で、一時QGraphicsItemポインターを初期化し、シーンに追加します。

mouseMoved()内で、それに応じて一時QGraphicsItemの座標を設定します。mouseReleasedの場合は、一時オブジェクトのコピーを作成してシーンに追加し、一時QGraphicsItem(線や長方形などの描画に使用していた)をシーンから削除します。

これの教訓は、QGraphicsView内にQPainterコンテキストがないことであり、そのpaintEvent()を無視する方がよいと思います。

これがこれにつまずくかもしれない誰かを助けることを願っています。

于 2009-07-13T09:36:21.527 に答える
1

別の可能性があります:ビューのdrawForegroundをオーバーライドします。描画する必要のあるアイテムの種類によっては、これは非常に簡単な解決策(マーカーラインのオーバーレイなど)である場合もあれば、シーンでカスタムアイテムを作成するよりも手間がかかる場合もあります(目的の結果によって異なります)。

于 2011-10-11T10:12:02.677 に答える