与QGraphicsItem一样,QGraphicsPixmapItem也有一个方法更新(x0,y0,width,height),以便仅在QGraphicsScene上部分地重新绘制像素图。调用此函数将在QGraphicsItem上调度一个QGraphcisScene ()(在Qt的事件循环中),并在执行此paint()后,将边界框(x,y,宽度,高度)重新绘制到边框。
不幸的是,无法使用边界框安排paint事件,这意味着QGraphicsPixmapItem::paint()被迫重新绘制整个QPixmap,因此在子类中重新实现此paint()-method无法仅部分更新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()调用随后分段为:
QPaintDevice:无法销毁正在绘制的绘制设备
我希望有一个替代的"item.setPixmap(&pixmap);",它不会重新绘制整个东西,但确实工作得很好。任何输入都是非常受欢迎的:)
发布于 2012-05-24 00:49:59
在我提出解决方案之前,有几点想法:
首先,Graphics View框架旨在成为显示多个图形对象的解决方案,因此一个大图像并不适合。当然,我意识到您的示例可能只是一个人为的示例,因此这一点可能并不真正适用。其次,由于框架是非常以转换为中心的,除非所有的转换都是相同的,没有滚动等,否则只重画QGraphicsItem的一部分可能没有意义。
无论如何,如果您只想绘制QGraphicsItem的一部分,您可以简单地存储需要更新的rect,并从paint()方法内部访问它。例如:
CustomItem::setPaintRect(const QRectF &rect)
{
paintRect = rect;
update();
}
CustomItem::paint(QPainter *painter /* etc. */)
{
painter->fillRect(paintRect, brush);
}https://stackoverflow.com/questions/10721935
复制相似问题