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);」に代わるものを用意したいと思います。これは、全体を再描画するわけではありませんが、うまく機能します。どんな入力でも大歓迎です:)