如何设置 QGraphicsItemGroup 的显示范围?

Posted

技术标签:

【中文标题】如何设置 QGraphicsItemGroup 的显示范围?【英文标题】:How can I set the display range of a QGraphicItemGroup? 【发布时间】:2017-12-25 23:54:32 【问题描述】:

我有一个 QGraphicsItemGroup 聚合了几个子项,我只想显示组的一部分。(不是子项的数量,区域)。就像这里的图片一样。

我要显示显示区域。

为此,我尝试了覆盖 QGraphicsItemGroup::boundingRect()。然而,什么都没有发生。我在 QT 文档中找到了这个,也许这就是为什么不起作用的原因。

QGraphicsItemGroup 的 boundingRect() 函数返回项目组中所有项目的边界矩形。

另外,我知道我可以更改 QGraphicsView 的大小以使其正常工作。但是我把 View 作为 CentralWidget,因为我还需要在 View 中显示其他对象,所以我不能改变 View 的大小。

如何设置 QGraphicItemGroup 的显示范围?

【问题讨论】:

【参考方案1】:

要执行此任务,我们可以通过返回定义可见区域的QPainterPath 来覆盖shape(),以便它传播到它的孩子,我们启用标志ItemClipsChildrenToShape

class GraphicsItemGroup: public QGraphicsItemGroup
public:
    GraphicsItemGroup(QGraphicsItem * parent = 0):QGraphicsItemGroup(parent)
        setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
    
    QPainterPath shape() const
    
        if(mShape.isEmpty())
            return QGraphicsItemGroup::shape();
        return mShape;
    
    void setShape(const QPainterPath &shape)
        mShape = shape;
        update();
    

private:
    QPainterPath mShape;
;

例子:

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    QWidget w;
    w.setLayout(new QVBoxLayout);

    QGraphicsView view;
    QPushButton button("click me");

    w.layout()->addWidget(&view);
    w.layout()->addWidget(&button);

    view.setScene(new QGraphicsScene);
    GraphicsItemGroup group;
    view.scene()->addItem(&group);
    auto ellipse = new QGraphicsEllipseItem(QRectF(0, 0, 100, 100));
    ellipse->setBrush(Qt::red);
    auto rect = new QGraphicsRectItem(QRect(150, 150, 100, 100));
    rect->setBrush(Qt::blue);
    group.addToGroup(ellipse);
    group.addToGroup(rect);

    QObject::connect(&button, &QPushButton::clicked, [&group]()
        QPainterPath shape;
        if(group.shape().boundingRect() == group.boundingRect())
            shape.addRect(0, 50, 250, 150);
        
        group.setShape(shape);
    );

    w.show();
    return a.exec();

输出:

完整的例子可以在下面的link找到。

【讨论】:

非常感谢!这就是我想要的!就一个问题。据我所知,QGraphicItem.shape() 似乎类似于 boundingRect()。就我而言,为什么 boundingRect 不起作用但 shape() 起作用? boundingRect(): ... 将项目的外边界定义为矩形;所有绘画都必须限制在项目的边界矩形内。 QGraphicsView 使用它来确定项目是否需要重绘。 shape():将此项的形状作为本地坐标中的 QPainterPath 返回。该形状用于许多事情,包括碰撞检测、命中测试和 QGraphicsScene::items() 函数。默认实现调用 boundingRect() 来返回一个简单的矩形形状,但是子类可以重新实现这个函数来为非矩形项返回一个更准确的形状。例如,圆形项目可能会选择返回椭圆形以更好地检测碰撞。 ,也就是说,第一个定义在哪里绘制,另一个定义什么是可见的。 :P 非常感谢!

以上是关于如何设置 QGraphicsItemGroup 的显示范围?的主要内容,如果未能解决你的问题,请参考以下文章

QGraphicsItemGroup组合中的一些细节

带有 QGraphicsItemGroup 的事件

从 QGraphicsScene/QgraphicsItemGroup/QGraphicsView 中正确删除项目

使 QGraphicsItemGroup 的子级不可选择

Qt 之 QGraphicsItemGroup

Qt 视图框架QGraphicsItem