Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Layers on QGraphicsView?

Hi I'm making an application that pulls data from a WFS and then displays those layers of data on a QGraphicsView on a widget. At the moment all layers are rendered and added to the same view meaning if I want to turn a layer of it means re-rendering all of it except that layer.

At the moment im adding a QGraphicsScene with Ellipse Items and Polygon Items added to it, to the graphics scene. I'm wondering if its possible to add multiple scenes to a graphics view or layers to a scene or something that would allow me to just hide/show certain points/polygons from a check box or something that simply hides a layer?

I know this is kind of vague but I'd appreciate any help.

Thanks.

like image 236
AngryDuck Avatar asked Aug 06 '13 08:08

AngryDuck


3 Answers

You only need one QGraphicsScene, but the key here is that all QGraphicsItems and QGraphicsObjects can be parented.

If you create a single QGraphicsItem or QGraphicsObject as a parent object, it doesn't need to draw anything, but can be used as the root for a layer's items.

Therefore, subclass from QGraphicsItem to create a QGraphicsItemLayer class that doesn't render anything and add all the ellipses, polygons etc that are required in the same layer as children of that QGraphicsItemLayer.

When you want to hide a layer, just hide the parent QGraphicsItemLayer object and all its children will be hidden too.

-------- Edited --------------

Inherit from QGraphicsItem: -

class QGraphicsItemLayer : public QGraphicsItem
{
    public:
        virtual QRectF boundingRect()
        {
            return QRectF(0,0,0,0);
        }

        virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
        {
        }
};

Create a layer item:

QGraphicsItemLayer* pLayer = new QGraphicsItemLayer;

Add the objects you want to the layer, note that pLayer is passed as the parent

QGraphicsEllipseItem = new QGraphicsEllipseItem(pLayer);

Assuming you've created the QGraphicsScene with a pointer to it called pScene: -

pScene->addItem(pLayer);

Then when you want to hide the layer

pLayer->hide();

Or display the layer: -

pLayer->show();
like image 83
TheDarkKnight Avatar answered Sep 27 '22 23:09

TheDarkKnight


Another way to go is QGraphicsItemGroup

Something like:

// Group all selected items together
QGraphicsItemGroup *group = scene->createItemGroup(scene->selecteditems());
...
// Destroy the group, and delete the group item
scene->destroyItemGroup(group);

So you can treat group as a layer and since group is also QGraphicsItem have all features like show()/hide() etc.

UPDATE: Changing Z-val for a group will allow you to implement things like 'move layer to top/bottom'

like image 44
evilruff Avatar answered Sep 28 '22 00:09

evilruff


I think you could try to partition your objects according to z value: see setZValue. Then introduce a mapping between layer id and indexing. A simple QStringList could do.

Of course, there are many details and variations that a practical solution will need to account for.

like image 35
CapelliC Avatar answered Sep 27 '22 23:09

CapelliC