QGraphicsView 上的图层?

8

你好,我正在制作一个应用程序,从WFS中提取数据,然后在小部件上的 QGraphicsView 上显示这些数据层。目前所有图层都被渲染并添加到同一个视图中,这意味着如果我想要关闭一层,则需要重新渲染除该层外的所有内容。

目前我正在向图形场景添加椭圆项和多边形项,以将它们添加到图形场景中。我想知道是否可能向图形视图添加多个场景或向场景添加图层,或者其他一些方法,使我能够仅通过复选框等隐藏/显示特定点/多边形,或者只是简单地隐藏一个图层?

我知道这有点模糊,但我会感激任何帮助。

谢谢。

3个回答

12

只需要一个QGraphicsScene对象,而关键在于所有的QGraphicsItemQGraphicsObject都可以被父级化。

如果您创建一个单独的QGraphicsItemQGraphicsObject作为父级对象,则无需绘制任何内容,但可以用作层中项目的根。

因此,从QGraphicsItem继承以创建一个不渲染任何内容的QGraphicsItemLayer类,并将所需的所有椭圆、多边形等添加为QGraphicsItemLayer的子项。

当您想要隐藏一个图层时,只需隐藏父QGraphicsItemLayer对象,它的所有子项也将被隐藏。

-------- 编辑 --------------

QGraphicsItem继承:

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

        virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
        {
        }
};
创建一个图层项:
QGraphicsItemLayer* pLayer = new QGraphicsItemLayer;

将您想要添加到该图层的对象添加进去,注意将pLayer作为父级传递。

QGraphicsEllipseItem = new QGraphicsEllipseItem(pLayer);

假设您已经创建了一个名为pScene的指向QGraphicsScene的指针:

pScene->addItem(pLayer);

当你想隐藏该层时

pLayer->hide();

或者显示该层:-

pLayer->show();

谢谢你的回答,但仅仅说做一个子类是行不通的,这样的回答可能适用于大多数问题,我需要的是如何实现这个子类。 - AngryDuck
2
为什么这个答案会收到负评?它完全回答了问题。AngryDuck,只需子类化QGraphicsItem并提供boundingRect()paint()的空实现即可。 - Stefan Majewsky
1
@StefanMajewsky,感谢您的支持。在SO上有很多懦夫只是匿名地点踩而不给出任何解释。如果我们能看到他们是谁,我认为这将是一个更好的地方。 - TheDarkKnight
正如@StefanMajewsky所说,这实际上非常简单,你只需要让对象成为父级,因此继承自QGraphicsItem(如果您想要信号和插槽,则继承自QGraphicsObject),然后使用空实现将其添加到场景并添加子项即可。 - TheDarkKnight
添加父项时,是否会自动添加其子项? - dani
@dani,是的 - 这就是文档所述的! - TheDarkKnight

9
另一种方法是使用 QGraphicsItemGroup。例如:

```

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

因此,您可以将组视为图层,并且由于组也是QGraphicsItem,因此具有显示()/隐藏()等所有功能。

更新:更改组的Z值将允许您实现诸如“将图层移到顶部/底部”之类的操作。


感谢回答,我会花一些时间尝试每个理论,然后根据哪个最有效果来选择一个答案,感谢帮助并点赞! - AngryDuck
最终我选择了这种方式,因为它最适合我所需的功能,虽然不完全是从你的代码中学来的,但基本上是一样的。我还使用了 group->showgroup->hide 来在图形视图中显示/隐藏多边形/点,效果很好,而且没有不必要的代码量。 - AngryDuck
如果QGraphicsItemGroup中的QGraphicsItem应该是可移动的,则需要调用QGraphicsItemGroup :: setHandlesChildEvents(false)。这将停止QGraphicsItemGroup尝试处理事件,并让子QGraphicsItems来处理它们。 - qknight

2
我认为你可以根据z值来划分你的对象:参见setZValue。然后介绍一种层ID和索引之间的映射关系。一个简单的QStringList就可以做到。
当然,实际解决方案需要考虑许多细节和变化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接