Navigating the WWidget Hierarchy
Added by Anonymous over 14 years ago
Hi All,
I'm undertaking my first Wt based project, so there may be an obvious answer to this, but I can't work it out from the doco.
I am trying to find a way to navigate the WWidget hierarchy. The WContainerWidget provides the "count()" and "widget()" methods to allow navigation from parent to children. However, not all parents inherit from WContainerWidget. An example of this is the WTable - I can not find a way to get at the children of the WTable!
Is there a consistent manner in which the WWidget tree can be navigated?
Thanks in advance,
Dan
Replies (3)
RE: Navigating the WWidget Hierarchy - Added by Anonymous over 14 years ago
I've worked this out - the WWebWidget class includes a method for getting at the WWidget children:
const std::vector<WWidget *>& children() const;
This should not be confused with the method on WObject:
const std::vector<WObject *>& children() const;
Strangely, for the same object, WObject::children() returns an empty vector when WWebWidget::children() does not. I would have expected the WWebWidget children to be a strict subset of the WObject children..
Cheers,
Dan
RE: Navigating the WWidget Hierarchy - Added by Koen Deforche over 14 years ago
Hey Dan,
I can see why this is indeed unexpected. The reason for not adding the widgets also to the WObject::children() container is (perhaps a case of misplaced) efficiency: in this way we do not need to dynamic_cast every object in WObject::children() to a widget to find out if it is a contained widget, and the other alternative is to duplicate the children vectors.
WWebWidget::children() is indeed a way to visit children widgets. This method is not provided by WCompositeWidget (the other type of WWidget) since that would (kind of) defeat the purpose of WCompositeWidget.
Just curious, what are you trying to do with this widget traversal ?
Regards,
koen
RE: Navigating the WWidget Hierarchy - Added by Anonymous over 14 years ago
Hi Koen,
Thank you for the prompt reply.
I understand the issue of efficiency, and your implementation is fine - just not so clear (to new users at least!) from the documentation.
I have a couple of reasons for needing to traverse the widget tree (apologies for this being awfully terse):
- Our application framework uses a tracing garbage collector to manage object lifetime. Many objects will only be reachable from their views, so we must keep track of which objects are referenced from WWidgets and ensure they are traced during garbage collection. Rather than storing a list of WWidgets that have references to our objects, it is much simpler (and arguably more efficient in practice) to traverse the widget tree looking for my widget classes that have references that need to be traced.
- Our notification and recalculation framework talks about "liveliness" - I am under contract to "start" and "stop" views as they are linked into and out of the widget tree. I walk the tree here starting/stopping views as required.
- When views are notified of a change, they merely make themselves as dirty. All recalculation occurs asynchronously. This is done by walking the widget tree and cleaning dirty nodes.
The third point is quite interesting - the ramification is that basically all changes are sent to the client via "server push" since the changes to the widgets happen asynchronously with respect to events generated by the widgets. I am very please to see that Wt is behaving itself when used in this manner - though I've only played with a coupe of widgets so far.
To your point about the WCompositeWidgets - so long as they are conceptually leaf nodes in the widget tree, then all is fine as I would not ever add any of my widgets under them. I've just had a quick look and this is not the case... Take WPanel for example - if I used this class directly, I would need to traverse into both the titleBarWidget and the centralWidget. It would be nice if Wt provided a method to traverse through the WCompositeWidgets also, but if that is not possible, I can sub-class classes like the WDialog and provide my own means of traversal. Your thoughts on this would be appreciated!
Cheers,
Dan