2012-05-23 7 views
0

QGraphicsPixmapItem은 QGraphicsItem과 마찬가지로 QGraphicsScene에서 부분적으로 만 픽스맵을 다시 그리기 위해 메서드 업데이트 (x0, y0, width, height)를 가지고 있습니다. 이것을 호출하면 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 
    } 
}; 

또 다른 옵션은 다음과 같이 부분적으로 그것에 QImage를 QGraphicsPixmapItem의 '내부 QPixmap'를 유지하고, 그릴 것 :

//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 (& 픽스맵을);", 어떤 모든 것을 다시 그리지는 않지만 잘 작동합니다. 모든 입력은 아주 잘 감사합니다 :) 내가 솔루션, 몇 가지 생각을 제시하기 전에

답변

1

가 :

먼저, 그래픽 프레임 워크는 많은 그래픽 개체를 표시하기위한 솔루션, 그래서 하나의 큰 이미지 ISN하기위한 것입니다보기 ' 정말 그 피팅. 물론, 나는 당신의 모범이 아마도 고의적 인 것이라고 생각합니다. 그래서이 점은 실제로 적용되지 않을 수도 있습니다. 둘째, 프레임 워크가 매우 변형 중심이기 때문에 QGraphicsItem의 일부를 다시 그리는 것이 모든 변환이 동일성이거나 스크롤링이없는 경우에는 의미가 없을 수도 있습니다.

어쨌든, QGraphicsItem의 경우 단순히 업데이트 할 rect를 저장하고 paint() 메서드 내부에서 액세스 할 수 있습니다. 예를 들면 다음과 같습니다.

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

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

첫 번째 요점에 대한 응답으로 :이 변환을 사용하여 확대/축소하는 것만입니다. 요점은 내가 확대하거나 축소 할 때마다 이것은 실제 QImage/QPixmap을 편집하는 것과 상호 배타적입니다. 또한 dirtyRect에 대해서 생각했지만 dirtyRectangles의 목록이어야합니다. 여러 업데이트가 각각 페인트 (경주 조건 등)를 호출하지는 못합니다. 어쨌든 당신의 대답은 유용합니다. "그래픽보기 프레임 워크"에 대한 대안이 있다면, 분명히 그것을 유출 느낄 수 있습니다 :) – Herbert