我正在创建一个在 Qt 中打开大图像 (2gb+) 的图像可视化工具。 我通过将大图像分成几个 512X512 的图 block 来做到这一点。然后我加载原始图像大小的 QGraphicsScene 并使用 addPixmap 将每个图 block 添加到 QGraphic 场景中。因此,对于最终用户来说,最终它看起来像是一张巨大的图像,而实际上它是场景中粘在一起的一系列连续的小图像。首先,这是一种好方法吗?
尝试将所有图 block 加载到场景中会占用大量内存。所以我想只加载 View 中可见的图 block 。我已经设法子类化 QGraphicsScene 并覆盖它的拖动事件,从而使我能够根据移动知道接下来需要加载哪些图 block 。我的问题是跟踪滚动条上的移动。有什么办法可以创建一个每次滚动条移动时都会调用的事件。子类化 QGraphicsView 不是一个选项。
最佳答案
QGraphicsScene
足够聪明,不会渲染不可见的内容,所以您需要做的是:
不是加载和添加像素图,而是添加包装像素图的类,并且仅在它们首次呈现时加载它。 (计算机科学家喜欢称之为“代理模式”)。然后您可以根据计时器卸载像素图。 (如果卸载得太快,它们将透明地重新加载。)您甚至可以将当前缩放级别通知此代理路径,以便它在渲染较小时加载较低分辨率的图像。
编辑:这里有一些代码可以帮助您入门。请注意,QGraphicsScene
绘制的所有内容都是 QGraphicsItem
,(如果您调用 ::addPixmap
,它会转换为 ...GraphicsItem
在幕后),所以这就是您想要子类化的内容:
(我什至还没有编译这个,所以“caveat lector”,但它在做正确的事;)
class MyPixmap: public QGraphicsItem{
public:
// make sure to set `item` to nullptr in the constructor
MyPixmap()
: QGraphicsItem(...), item(nullptr){
}
// you will need to add a destructor
// (and probably a copy constructor and assignment operator)
QRectF boundingRect() const{
// return the size
return QRectF( ... );
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget){
if(nullptr == item){
// load item:
item = new QGraphicsPixmapItem( ... );
}
item->paint(painter, option, widget);
}
private:
// you'll probably want to store information about where you're
// going to load the pixmap from, too
QGraphicsPixmapItem *item;
};
然后您可以使用QGraphicsScene::addItem(...)
QGraphicsScene
关于c++ - 用 QGraphicsScene 和 QGraphicsView 平铺,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5927665/