I’ve been using this function for a long time and now I seem to have found a bug in it. When called with the name of a template instance, it returns correctly but none of the custom properties or methods are available.
def traverse_components( obj, visit ):
##
## recursively visit all components contained by obj
##
if obj is not None:
visit( obj )
try:
c = obj.getComponents()
except AttributeError:
pass
else:
for x in c:
traverse_components( x, visit )
def find_component( root, objname ):
##
## finds the 'first' occurence of an object named objname.
## 'first' as defined by the .getComponents function
##
class found: pass
found.obj = None
def finder( s ):
def __finder( obj ):
if found.obj is None and hasattr( obj, 'name' ) and obj.name == s:
found.obj = obj
return __finder
project.util.traverse_components( root, finder( objname ))
## could be None
return found.obj
so this sequence produces identical printed output:
obj = window.rootContainer.getComponent( 'Template Instance' )
print( repr( obj ))
obj2 = project.util.find_component( window.rootContainer, 'Template Instance' )
print( repr( obj2 ))
However, if ‘Template Instance’ has a property named ‘Value’ and a method named ‘set_value’, these work:
obj.Value = 100
obj.set_value( 100 )
and these do not:
obj2.Value = 200
obj2.set_value( 200 )
In both cases the error is “object has no attribute ‘set_value’”
Any ideas? I use this function all over the place to avoid the issue of control name/paths changing when grouping and ungrouping objects.
ed: Some extra info. I lied about repr() returning identical results. There is a slight difference in the obj2 output:
[obj] com.inductiveautomation.factorypmi.application.components.template.TemplateHolder[Test,130,170,180x120,layout=com.inductiveautomation.factorypmi.application.components.template.TemplateHolder$1,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
[obj2] com.inductiveautomation.factorypmi.application.components.template.TemplateHolder[Test,130,170,180x120,invalid,layout=com.inductiveautomation.factorypmi.application.components.template.TemplateHolder$1,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
That invalid there. No idea what it is, but it’s different.