0

QGraphicsPixmapItem は、QGraphicsItem と同様に、QGraphicsScene で部分的にのみ pixmap を再描画するために update(x0, y0, width, height) メソッドを持っています。これを呼び出すと、QGraphicsItem で paint() (Qt のイベント ループ内) がスケジュールされ、この paint() が実行された後、バウンディング ボックス (x、y、幅、高さ) が QGraphcisScene に再描画されます。

不幸な部分は、バウンディング ボックスでペイント イベントをスケジュールする方法がないことです。つまり、QGraphicsPixmapItem::paint() は QPixmap 全体を強制的に再ペイントする必要があるため、サブクラスでこのペイント() メソッドを再実装しても、 QPixmap を部分的にしか更新しないため、QPixmap への小さな (ローカルの) 更新が容認できないほど遅くなります。

このようなサブクラスは次のようになります。

class LocallyUdatablePixmapItem : public QGraphicsPixmapItem {
private:
    QImage ℑ
public:
    LocallyUdatablePixmapItem(QImage &img) : QGraphicsPixmapItem(), image(img) {}

    paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QStyle *widget) {
         //locall update, unfortunately without a boundig box :( therefore -> slow
    }
};

別のオプションは、QGraphicsPixmapItem の「内部 QPixmap」を保持し、次のように QImage を部分的に描画することです。

//some initialization of variables
QGraphicsScene scene = ...;
QImage img = ...; //some image data that I wish to manipulate from time to time
QPixmap pixmap  = QPixmap::fromImage(this->shown);
QPainter painter = new QPainter(&this->pixmap);
QGraphicsPixmapItem item = this->addPixmap(this->pixmap);
item->setPixmap(this->pixmap);
//this should not matter, but actually it does, as I will explain shortly
//delete painter;
//painter = new QPainter(item->pixmap());

//For some reason I decide to update (manimulate) img within a small boundigbox
int x0, y0, width, height; //bounding box, assume they are set to whatever is appropriate for the previous update
painter->drawImage (x0, y0, img, x0, y0, width, height);
//now the pixmap is updated, unfortunately the item is not. This does not affect it:
item->update(x0, y0, width, height);
//nor does this:
item->update();
//but this, which makes the whole thing slow, does:
item.setPixmap(&pixmap);

それを修正するためにピックスマップを設定する必要があることを考えると、初期化で何らかの形で設定されていないと想定したため、前述の行のコメントを外すことは良い考えのように思えました。残念ながら、drawImage() 呼び出しは次のように segfault します。

QPaintDevice: ペイント中のペイント デバイスを破棄できません

「item.setPixmap(&pixmap);」に代わるものを用意したいと思います。これは、全体を再描画するわけではありませんが、うまく機能します。どんな入力でも大歓迎です:)

4

1 に答える 1

1

解決策を提案する前に、いくつか考えてみましょう。

まず、Graphics View フレームワークは、多数のグラフィック オブジェクトを表示するためのソリューションであることを目的としているため、1 つの大きな画像は実際には適切ではありません。もちろん、あなたの例はおそらく不自然なものであることはわかっているので、この点は実際には当てはまらないかもしれません. 第二に、フレームワークは非常に変換中心であるため、すべての変換が同一である場合やスクロールがない場合などを除き、QGraphicsItem の一部のみを再描画するのは意味がない場合があります。

とにかく、QGraphicsItem の一部だけを描画したい場合は、更新が必要な rect を保存し、paint()メソッド内からアクセスするだけです。例えば:

CustomItem::setPaintRect(const QRectF &rect)
{
    paintRect = rect;
    update();
}

CustomItem::paint(QPainter *painter /* etc. */)
{
    painter->fillRect(paintRect, brush);
}
于 2012-05-23T16:49:58.620 に答える