>>charley spaketh:
>> <snip, set custom property in "onChildrenChanged">

>Michael respondeth:
> Yes, it should work <snip>

Yes, it works, it was my error.  What I'm doing is a little
more complicated, and there was enough obfuscation
for me to confuse myself.  ;-)

I now have something that "works", but I want to get
opinions on whether my solution is "stupid" or "best practice".

After further investigation, here's what's going on:

- I create a "myParent" Item{}
- I create "child" items that are not yet parented to my "myParent"
- I explicitly parent the child items with "{ parent: myParent }"

The above works.  My confusion was based on:

- the "child" items have application-specific properties
to be set when re-parented (e.g., layout attributes)

- the "myParent" had *additional* (hard-coded) children,
like background rendering, that do not have the
application-specific properties of these "transient"
children.

Because my "onChildrenChanged()" in "myParent"
merely iterated all its children, it attempted to access
application-specific attributes in the "hard-coded"
children (when it should have only accessed those
attributes in the transient children).

Because QML is typesafe, these failed accesses
on the hard-coded children triggered an exception.
IMHO, this is "good" (I am pleased QML provides this
safety -- it backs me up in my design decisions).

QUESTION:  What is the preferred mechanism to
"test" children for type, or for "id:", or any distinguishing
characteristic?

For example, my solution is to "test" for my application-
specific attribute, at which point I "conclude" this is
a transient child:

Item {
  id:  myParent
  onChildrenChanged: {
    for(var i = 0; i < myParent.children.length; ++i) {
      if(myParent.children[i].myApplicationSpecificAttribute === undefined) {
          // Not transient child
      } else {
          // Is transient child
         myParent.children[i].myApplicationSpecificAttribute = 1.0;
      }
    }
  }
}

This works.  However, I wanted to "see" what was in the child
to understand what I could work with, so I printed it out:

...inserting this snippet to inspect each child...

  for (var myKey in myParent.children[i]) {
    console.log("child[" + myKey + "] == (" +
mySdGlobe.children[i][myKey] + ")");
  }

...I get something like:

-----------------------------------------
child[childrenChanged] == ([object Object])
child[scaleChanged] == ([object Object])
child[heightChanged] == ([object Object])
child[deleteLater] == ([object Object])
child[colorChanged] == ([object Object])
child[yChanged] == ([object Object])
child[gradient] == (null)
child[state] == ()
child[top] == (QVariant(QDeclarativeAnchorLine))
child[opacityChanged] == ([object Object])
child[smooth] == (false)
child[width] == (0)
child[visible] == (true)
child[visibleChanged] == ([object Object])
child[rotationChanged] == ([object Object])
child[transitions] == ([object Object])
child[childrenRectChanged] == ([object Object])
child[data] == ([object Object])
child[clip] == (false)
child[resources] == ([object Object])
child[anchors] == (QDeclarativeAnchors(0x60382b8))
child[right] == (QVariant(QDeclarativeAnchorLine))
child[parent] == (QDeclarativeItem(0x5ef5850))
child[verticalCenter] == (QVariant(QDeclarativeAnchorLine))
child[xChanged] == ([object Object])
child[pos] == ([object Object])
child[myDoubleChanged] == ([object Object])
child[focus] == (false)
child[activeFocusChanged] == ([object Object])
child[states] == ([object Object])
child[color] == (#ffffff)
child[baselineOffset] == (0)
child[updateMicroFocus] == ([object Object])
child[horizontalCenter] == (QVariant(QDeclarativeAnchorLine))
child[myDouble] == (0)           <=========MY APPLICATION-SPECIFIC ATTRIBUTE
child[bottom] == (QVariant(QDeclarativeAnchorLine))
child[mapFromItem] == ([object Object])
child[border] == (QDeclarativePen(0x6040890))
child[forceActiveFocus] == ([object Object])
child[baselineOffsetChanged] == ([object Object])
child[baseline] == (QVariant(QDeclarativeAnchorLine))
child[transformOriginPoint] == ([object Object])
child[scale] == (1)
child[left] == (QVariant(QDeclarativeAnchorLine))
child[parentChanged] == ([object Object])
child[transformOriginChanged] == ([object Object])
child[radiusChanged] == ([object Object])
child[activeFocus] == (false)
child[childrenRect] == ([object Object])
child[enabledChanged] == ([object Object])
child[effect] == (null)
child[children] == ([object Object])
child[opacity] == (1)
child[rotation] == (0)
child[zChanged] == ([object Object])
child[clipChanged] == ([object Object])
child[focusChanged] == ([object Object])
child[childAt] == ([object Object])
child[mapToItem] == ([object Object])
child[transform] == ([object Object])
child[transformOrigin] == (4)
child[smoothChanged] == ([object Object])
child[objectName] == ()
child[x] == (0)
child[enabled] == (true)
child[y] == (0)
child[z] == (0)
child[widthChanged] == ([object Object])
child[stateChanged] == ([object Object])
child[height] == (0)
child[radius] == (0)
-----------------------------------------

Good stuff.  I can see exactly what's going on.

I don't want to dig too deeply into QML internals (I assume some
of these keys may change), but I was looking for an "id:" field to
uniquely identify the object, and didn't find it (and the "objectName"
field is empty, so I assume that is for different purposes).

I'm sure there are a zillion options.  For example, I could
create a "myType" field to define my own types, check
for specific fields like I'm doing, or come up with other
heuristics (for example, in my debugging, I uniquely identified
objects by setting universally unique values to "height").

However, I was curious if there was a "preferred/best-practice"
method, since I ASSUME this is a COMMON case:

?COMMON_CASE:  Rich application-specific QML element
with (hard-coded) internal children, but which *also* manages
transient (child) elements that are periodically re-parented
among different QML elements.

For example, this is the common case for any QML element
that performs layout upon its children.  Because QML is
OUTSTANDING for such dynamic re-parenting (through
its use of states and transitions), I'd assume many applications
want to iterate "transient" children separate from "hard-coded"
children.

SUMMARY QUESTION:  What is best practice to separately iterate
"transient" children from "hard-coded" children?

Thanks!

--charley
_______________________________________________
Qt-qml mailing list
Qt-qml@trolltech.com
http://lists.trolltech.com/mailman/listinfo/qt-qml

Reply via email to