Inline component in a component
-
[quote author="Gerolf" date="1301920550"][quote author="Tipiak" date="1301919705"][quote author="Gerolf" date="1301917914"]A type is not the same as a typedef!
[/quote]
uh? Once defined, the type defined by the typedef is a type, or missed a something obvious for years.
[/quote]A typedef is just another name for an existing type or for example a template. So typedef itself does not create a real type, it just gives another name for a type, more like a reference does not create an object, it#s just another name :-)
[/quote]
That's why i mentioned "type aliasing" few lines later. It more than a name and less a than "new" type declaration, in this case.
[quote author="Gerolf" date="1301920550"]
otherwise, such things would not work:
@
class A
{
puiblic:
explicit A();
explicit A(const A&);
}//typedef B A; << wrong!
typedef A B;A myObj;
B myObj2;
A myObj3(myObj2);
@[quote author="Tipiak" date="1301919705"]
Again, that's not what the doc tells me! Or we have not the same defnition of "created".
Mine says it's when the rectangle is created, whit his children, initialized and Component.onCompleted called. It's not the case until you load your component with a loader.
[/quote]TestPage.qml
@
item {
id: item1
Component {
id: inneritem
Rectangle {
color: "red"
width: 10
height: 10
}
TestPage{
}
}
}
@If you instantiate the type TestPage, all inner objects are created, right? including the height, width, etc. So if Rectangle is instantiated, also TestPage sub object will be created. This is the recursion![/quote]
Your example is wrong (again :) ). A Component, inline or not, cannot contain more than one root item.
But let's say:
@
import Qt 4.7
Item {
id: item1
width: 20
height: 20
Component {
id: inneritem
Rectangle {
color: "red"
width: 10
height: 10
// TestPage{
// }
Component.onCompleted: {
console.log("Hello")
}
}
}
Loader {
sourceComponent: inneritem
}
}
@if you comment the Loader, "hello" is not displayed. But if you uncomment TestPage you've got the "recursive instantiation" error.
-
One (really! - promised!) last try:
The big precondition is: you saved this snippet in TestPage.qml:
@
item {
id: item1
Component {
id: inneritem
TestPage {
}
}
}
@If you instantiate your component (and you will instantiate it eventually, otherwise this whole discussion is plain uselsess), the interpreter eventually comes along line 5. As TestPage is no builtin thingie, it tries to resolve it. It looks into the filesystem and happily finds TestPage.qml (because it always looks for name-of-the-thingie.qml); so nice, it tries to load it, but only to find out that it is the same file as it is processing right at the moment - boom! Recursion!
So please do yourself a favor and rename TestPage.qml to blafasel.qml and try again. I guess you will get a "component TestPage not found" error or something similar.
-
I realize this is very old, but the explanations of why-you-cannot-do-this don't really show why-you-cannot-do-this.
Yes, documentation says a component is only loaded when a loader asks for it. But a component MUST BE FULLY DEFINED in order to run.
The original sample code does not have any syntax errors, so it compiles, but what happens when you try to instantiate (or even dynamically load) TestPage?
QML loads the definition for TestPage, from TestPage.qml, and starts creating the things inside of it.
QML gets to the Component definition, begins to instantiate THE COMPONENT, and says, "Hey, a component, I need to load and prepare the definition of this component so I can instantiate it when the loader asks for it"
QML starts building the definition of Component. It is not instantiating the contents of the component, but it IS still instantiating TestPage.
QML runs into "TestPage" as thing inside of the Component.
QML says "Oh, I know were that definition is, in TestPage.qml! Oh, wait a minute, I'm currently INSTANTIATING TestPage, and it looks like something inside of TestPage needs everything inside of TestPage in order to exist.... Hmmmm...."
At this point the QML runtime engine can either:
A. be stupid and just keep blindly going, or
B. be a little smart and realize that if it is instantiating an object and it runs into a requirement for that same object somewhere in the instantiation tree, it has recursive dependencies.No, the inner TestPage is not technically instantiated.
But YES, the inner TestPage must be "completely known" before the Component instantiation can complete.
One can quibble about why the error says "recursive instantiation", but it is technically correct, since it IS instantiating and it HAS encountered a recursive dependency.
If the Component content is inline (and the example is inline), all of that content must be parsed and prepared (including subordinate objects) so that it "knows what to do" when loaded.
If you really want to dynamically load something, look at Qt.createComponent:
http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html
The object created must be stored in a 'var', so this is much more like the pointer examples called out in the discussion.