为什么不发出childrenRectChanged,而是将childrenRect称为“修复程序”呢?

问题描述

目标

我需要知道QQuickItem的子类Foo的子代的集合几何何时,如何变化。

问题

我已将lambda连接到QQuickItem::childrenRectChanged信号,但从未发出过。奇怪的是,如果我在某个地方打电话给childrenRect,信号就会开始发出。 childrenRect是一种getter方法,而不是setter方法,因此我认为没有必要进行此“修复”。

问题

为什么看似无关的调用“修复”了信号的发射,以及如何在不调用childrenRect的情况下按预期方式工作?

可复制的示例

以下是我准备演示此问题的示例:

Foo.h

#include <QQuickItem>

class Foo : public QQuickItem
{
    Q_OBJECT
public:
    explicit Foo(QQuickItem *parent = nullptr) :
        QQuickItem(parent) {
        childrenRect(); // After commenting this childrenRectChanged is not emitted anymore
        connect(this,&Foo::childrenRectChanged,[this](){
            qDebug() << childrenRect();
        });
    }
};

该类在 main.cpp 注册,如下所示:

qmlRegisterType<Foo>("Foo",1,"Foo");

,并通过以下方式在 main.qml 中使用:

import QtQuick 2.15
import QtQuick.Window 2.15
import Foo 1.0

Window {
    width: 300; height: 400; visible: true; color: "black"
    title: qsTr("Children Rect")

    Foo {
        anchors.centerIn: parent

        Rectangle {
            anchors.bottom: lightMid.top
            anchors.horizontalCenter: parent.horizontalCenter
            width: 50; height: width; radius: 0.5*width
            color: "red"
        }

        Rectangle {
            id: lightMid

            anchors.centerIn: parent
            width: 50; height: width; radius: 0.5*width
            color: "yellow"
        }

        Rectangle {
            anchors.top: lightMid.bottom
            anchors.horizontalCenter: parent.horizontalCenter
            width: 50; height: width; radius: 0.5*width
            color: "green"
        }
    }
}

编辑

QQuickItem::childrenRect 的文档中说:

属性保存商品的共同位置和大小 孩子们。

如果需要访问集合几何,此属性很有用 项子项的大小,以便正确调整其大小。

访问功能

QRectF childrenRect()

但是,正如注释中提到的@Amfasis一样,此方法不仅仅是简单的getter。这是the code

QRectF QQuickItem::childrenRect()
{
    Q_D(QQuickItem);
    if (!d->extra.isAllocated() || !d->extra->contents) {
        d->extra.value().contents = new QQuickContents(this);
        if (d->componentComplete)
            d->extra->contents->complete();
    }
    return d->extra->contents->rectF();
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)