使用QGraphicsScene和QGraphicsView进行平铺 [英] Tiling with QGraphicsScene and QGraphicsView

查看:651
本文介绍了使用QGraphicsScene和QGraphicsView进行平铺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个图像可视化工具,可以在Qt中打开大图像(2gb +). 我是通过将大图分成512X512的多个图块来实现的.然后,我加载原始图像大小的QGraphicsScene并使用addPixmap将每个图块添加到QGraphic Sc​​ene上.因此,最终,对于最终用户而言,它看起来像是一幅巨大的图像,而实际上它是在场景中粘在一起的连续的较小图像阵列.首先,这是一种好方法吗?

I'm creating a image visualizer that open large images(2gb+) in Qt. I'm doing this by breaking the large image into several tiles of 512X512. I then load a QGraphicsScene of the original image size and use addPixmap to add each tile onto the QGraphic Scene. So ultimately it looks like a huge image to the end user when in fact it is a continuous array of smaller images stuck together on the scene.First of is this a good approach?

尝试将所有图块加载到场景上会占用大量内存.因此,我正在考虑仅加载视图中可见的图块.我已经成功地继承了QGraphicsScene的子类并覆盖了它的drag事件,从而使我能够根据运动知道接下来需要加载哪些图块.我的问题是在滚动条上跟踪运动.有什么方法可以创建一个每次滚动条移动都被调用的事件.不能将QGraphicsView子类化.

Trying to load all the tiles onto the scene takes up a lot of memory. So I'm thinking of only loading the tiles that are visible in the view. I've already managed to subclass QGraphicsScene and override its drag event thus enabling me to know which tiles need to be loaded next based on movement. My problem is tracking movement on the scrollbars. Is there any way I can create an event that get called every time the scrollbar moves. Subclassing QGraphicsView in not an option.

推荐答案

QGraphicsScene足够聪明,无法呈现不可见的内容,因此您需要执行以下操作:

QGraphicsScene is smart enough not to render what isn't visible, so here's what you need to do:

添加包装像素类的方法,而不是加载和添加像素图,并且仅在首次渲染像素图时才对其进行加载. (计算机科学家喜欢将其称为代理模式").然后,您可以根据计时器卸载像素图. (如果卸载太早,它们将被透明地重新加载.)您甚至可以将当前缩放级别通知此代理路径,以便在将其渲染得较小时加载较低分辨率的图像.

Instead of loading and adding pixmaps, add classes that wrap the pixmap, and only load it when they are first rendered. (Computer scientists like to call this a "proxy pattern"). You could then unload the pixmap based on a timer. (They would be transparently re-loaded if unloaded too soon.) You could even notify this proxy path of the current zoom level, so that it loads lower resolution images when they will be rendered smaller.

这是一些入门的代码.请注意,QGraphicsScene绘制的所有内容都是QGraphicsItem((如果调用::addPixmap,则会在幕后将其转换为...GraphicsItem)),所以这就是您要继承的类:

here's some code to get you started. Note that everything that QGraphicsScene draws is a QGraphicsItem, (if you call ::addPixmap, it's converted to a ...GraphicsItem behind the scenes), so that's what you want to subclass:

(我什至没有编译过这个,所以是"caveat lector",但它做对了;)

(I haven't even compiled this, so "caveat lector", but it's doing the right thing ;)

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和QGraphicsView进行平铺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆