[Qt-qml] QML element initialization

Adriano Rezende adriano.rezende at openbossa.org
Mon Aug 16 23:06:25 CEST 2010


Hi,

While porting a library to QML, I've got into the following situation:

I have wrapper classes WA and WB that are QDeclarativeItems. These
classes have internal pointers to the library objects NA and NB,
respectively.
NA is a factory for NB objects (NB constructors are protected). So to
construct a NB object, a NA object is needed.

Suppose the following scenario with the files below:

=== main.qml =======================
import MyLib 1.0 as Lib

Lib.WA {
   id: wa

   Lib.WB { id: wb1; }

   WBX { id: wb2; }

   MouseArea {
       anchors.fill: parent
       onClicked: {
           var c = Qt.createComponent("WBX.qml");
           var wb3 = c.createObject(wa);
       }
   }
}
====================================

=== WBX.qml ========================
import MyLib 1.0 as Lib

Lib.WB {

}
====================================


WB code is as follows:

====================================
void WB::classBegin()
{
    // get parent (WA) and create internal object.
    // if parent is null shows an error message ('parent required')
}

void WB::componentComplete()
{
   // all properties have been set and I know my parent... ready to start.
}
====================================

To create wb1 object, the code works perfectly, since the parent is
set before the classBegin() call.

To create wb2 object, classBegin() is called twice; in the first call
parent is null, in the second call parent is not null (probably this
is a bug).

To create wb3 object, the code will fail since the parent is set only
after classBegin() and componentComplete() methods are called. I'll
have to cache all property changes, since I don't have the internal
object during the wrapper initialization, and wait for parent change
notification to initialize the object.

So in order to work in these 3 cases I have to test which case I'm handling.

Wouldn't it be better if the parent was set (if it's not null) before
classBegin() in all cases to avoid corner cases like the above? This
would ease the port of several libraries that have the same hierarchy
dependency.

Looking at the VME code, it seems that CreateObject and
CreateSimpleObject instructions use the object stack to retrieve its
parents. But when the method QDeclarativeVME::run is called from the
QDeclarativeComponent side it sends an empty stack, so no parent is
set at construction time.

Somebody knows if there are some side effects to make it possible? Or
if there is a reason to have the current behavior?

Br,
Adriano



More information about the Qt-qml mailing list