Goal
I need to know when and how the collective geometry of the children of Foo
, a subclass of QQuickItem
, changes.
Problem
I have connected a lambda to the QQuickItem::childrenRectChanged
signal, but it is never emitted. Strangely enough, if I call childrenRect
somewhere, the signal starts getting emitted. childrenRect
is a getter method, not a setter, so I see no reason for this "fix".
Question
Why a seemingly unrelevant call "fixes" the emition of the signal and how to make this work as expected without calling childrenRect
?
Reproducible example
Here is an example I have prepared to demonstrate the issue:
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();
});
}
};
The class is registered in main.cpp like this:
qmlRegisterType<Foo>("Foo", 1, 0, "Foo");
and used in main.qml in the following way:
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"
}
}
}
Edit
The documentation of QQuickItem::childrenRect
says:
This property holds the collective position and size of the item's children.
This property is useful if you need to access the collective geometry of an item's children in order to correctly size the item.
Access functions:
QRectF childrenRect()
However, as @Amfasis mentioned in the comments, this method is not just a simple getter. Here is 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();
}