Please add the name argument to the add_component function.
The first example on the documentation of add_component would be xyp.add_component(lbl, x=10, y=10, name='hello_label') and it could be reached with xyp.hello_label.
When you drag and drop components onto your Form in the visual designer, components are set as attributes on the Form object. The purpose of component naming is to let you refer to these components as attributes on your Form object (e.g self.hello_label).
This isnāt necessary when you create components in code (such as lbl in your example), as itās straightforward to set the attributes yourself:
I often use add_component in a loop. In those cases, I may want to give my components ānamesā dynamically based on a list.
I can use setattr to accomplish this. Do you see any problems with this approach?
For example:
names=['a', 'b', 'c']
for n in names:
l=Link(text=n)
setattr(self, n, l) # assigning a new property based on a string
self.add_component(l)
# referencing by custom name
print(self.c.text)
# returns
'c'
The other thing is that, in a previous post, Ian mentioned that it was not a great idea to add arbitrary attributes onto a component (e.g., self.my_button.name='foo'). Instead, he recommended to use the tag property to store attributes.
Is it still recommended to use the tag property to store arbitrary attributes on components?
Thanks for the example and yes, youāre exactly right - the recommended approach would be to use the tag property to store attributes on components:
names=['a', 'b', 'c']
self.tag = {'my_extra_components':{}}
for n in names:
l=Link(text=n)
self.tag['my_extra_components'][n] = l
self.add_component(l)
print(self.tag['my_extra_components']['c'].text) # prints 'c'
And for my example above:
xyp = XYPanel(width=400, height=400)
self.add_component(xyp)
lbl = Label(text='I am a label')
xyp.add_component(lbl, x=10, y=10)
self.tag['hello_label'] = lbl
print(self.tag['hello_label'].text) # prints 'I am a label'
I would like a clarification on the clarification: is it always a bad idea to add arbitrary attributes to any component, including forms, or forms are an exception to the rule?
In my forms I often fill the __init__ with self.something = something. I just cloned a few apps from the blog page and I see the same pattern.
bringing up this thread again - clarification on the clarificationā¦
Is it the recommended approach because name_conflicts or another reasonā¦
I see the tag component as super useful and a convenient place for certain things.
Especially for components that are not a Form which is when I tend to use it mostā¦
But for a Form I donāt typically use it because it rarely seems pythonic to me.
(apart from when it does )
I think your initial post @bridget, to me, seems the preferred way to do something like thatā¦
in this post from a few years ago @ian mentions the phasing out of directly adding attributes to components. Also linked above
But like @stefano.menci mentions its also used for most tutorials and in most situations seems like the best approachā¦
Is there a distinction here between components that may have something like this phased outā¦
Surely the Form will never have this phased out since itās a python class with a __dict__
Itās perfectly fine (and often very useful!) to add arbitrary attributes to Forms. For components, the recommended approach is to use the tag property, to avoid name conflicts, as @stucork points out.