2012-05-23 208 views
0

QGraphicsPixmapItem與QGraphicsItem一樣,有一個方法更新(x0,y0,width,height),以便僅在QGraphicsScene中重新繪製一部分像素圖。調用此方法將在QGraphicsItem中調度paint()(在Qt的事件循環中),並且在執行paint()之後,boundingbox(x,y,width,height)將被重繪到QGraphcisScene。QGraphicsPixmapItem

不幸的是,沒有辦法用boundingbox來安排paint-event,這意味着QGraphicsPixmapItem :: paint()被強制重新繪製整個QPixmap,因此在一個子類中重新實現了這個paint()方法無法僅部分更新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); 

鑑於我需要設置pixmap來修復它,我認爲它不知道在初始化設置,因此取消註釋前面提到的行似乎是一個不錯的主意。不幸的是,的drawImage()調用,然後出現segfaults到:

的QPaintDevice:不能銷燬被塗

我想有到另一種塗料設備「item.setPixmap(&像素圖);」,這不重繪整個事物,但確實很好地工作。任何輸入是很好的讚賞:)

回答

1

之前,我提出了一個解決方案,有幾個想法:

首先,圖形視圖框架旨在顯示許多圖形對象的解決方案,所以一個大圖像ISN」真的很適合。當然,我認識到你的例子可能只是一個人爲的例子,所以這一點可能不適用。其次,由於框架非常以變換爲中心,所以只重繪部分QGraphicsItem可能沒有意義,除非所有變換都是標識,沒有滾動等。

反正,如果您只想繪製部分的QGraphicsItem,您可以簡單地存儲需要更新的矩形,並從paint()方法中訪問它。例如:

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

CustomItem::paint(QPainter *painter /* etc. */) 
{ 
    painter->fillRect(paintRect, brush); 
} 
+0

迴應你的第一點:我只使用這些轉換放大和縮小,僅此而已。重點是,無論何時放大或縮小,這都與編輯實際的QImage/QPixmap互斥。我也想過一個dirtyRect,但這應該是一個dirtyRectangles的列表,因爲我不確定多個更新每次都會調用paint(競爭條件等)。無論如何,你的答案似乎有用。如果你有任何「圖形視圖框架」的替代品,顯然可以隨意泄漏它:) – Herbert

相關問題