So I’ve read how we CAN’T find components by name.
But we CAN tag them via .tag property.
But these CAN’T be set at design time (or can they?).
Q. So what’s the best way to cycle thru EXISTING components and tag them if we don’t know which eg drop-box we’re looking at?
The tag property can be set through code or in the IDE.
If you want to keep track of components that are created programatically, it is probably easiest to set the tag property at the time the components are created. You can see some examples here.
That said, if you need to loop through some components and set their tags, your approach will differ depending on the setup of your form. You may need to resort to using numerical indexing and/or using type(DropDown)
to keep track of which type of component you are operating on.
If you have a specific example you can share, that would make it easier to provide more specific help.
@alcampopiano, in the IDE, whenever I see “tag” in the component properties, it’s always labelled ‘Set at runtime’:
It remains that way no matter what form component I click on.
When do you see it otherwise?
1 Like
Thanks for clarifying that.
I was referring to binding data to the tag in the IDE:
Since Data Binding assigns values at run-time, not design time, I believe that the OP was referring to the , which (apparently) can’t be set at design time.
Frankly, I’m not even sure why it’s displayed at all. At design time, it has no value to display. And if one can’t be entered at design time, why bother taking up screen space? I must be missing something.
I’m sure you are correct.
My thinking was that setting a tag to say a plain string in the IDE is functionally equivalent to setting “at design time”. That is, nothing else that happens in the code can change that tag’s value, unless it is overwritten explicitly.
I must admit, I don’t think I’ve ever set a tag in this way though (i.e., to a plain string). Usually I would set it in code and/or with binding from a DB/dict.
Good point. I wonder why it is there.
You’ve just exposed a wonderful idea, though. Any Python expression could be used in your Data Binding example. { 'name1': 5, 'name2': "my name" }
should work just as well!
I think you’ve just found the answer @paul.k.pallaghy was looking for!
1 Like
So, folks, I think you’re saying I can add a tag at design time?
Thanks!
(But what I don’t get is why none of you do this already? How do you cycle through eg 10 comboboxes if you don’t know which one is which? Sometimes it’s nice to have them at DESIGN time if they will be fixed. But that’s neither here nor there . . )
We do indeed tag components in many different ways. For example:
-
if building components programatically in a loop, we use the loop to set tags with code (also this is mentioned in the post I linked to above)
-
often, if there are not too many, I set some tags in the init
-
as mentioned above, you may set them in the IDE (with bindings, python expressions, plain strings)
-
often sets or groups of components have bindings to data table rows or dictionaries, again, this is where binding comes in handy
I very rarely have to loop through groups of components where there is no prior way of tagging or identifying them. That is, I rarely have to resort to numerical indexing (since this can make for a brittle design).
If you have a specific example you can share where you find the identification/tagging of components difficult to do in a convenient way, please share so we can help more directly.
1 Like
My example is this:
I have, at DESIGN time, 8 comboboxes.
They are where I want them. I don’t want to create them programmatically.
BUT, programmatically I need to do things to them in a loop.
eg:
for combobox in comboboxes:
if 'dog' in combobox.tag:
# do doggy things
if 'cat' in combobox.tag:
# do catty things
I might have 4 doggy comboboxes and 4 catty comboboxes and I don’t want to have to:
self.dog1combobox.property = value
etc for each one
Since I can’t access the name property, how can I programmatically loop through them and know WHICH one I am getting (without actually hard-coding the names)?
Tagging seems to be the only way.
Or have I missed something that you guys all know and aren’t telling me.
Based on what I can gather from your example, I think that setting up the tags ahead of time (say in the init
) and looping through is the way to go. Example,
for box in combobox_container.get_components():
if box.tag.name=='dog'
# do something
elif box.tag.name=='cat':
# do something
.
.
.
However, I suspect that your actual application may be able to make use of event triggers and perhaps a repeating panel in order to make identification of large groups of similar components easier, and maybe this would reduce code duplication. Without knowing more about the specific use case it is hard to tell. But either way, a large explicit “if” statement is not that bad I suppose.
1 Like
You can also make lists of components and iterate through them. This allows you to iterate over components regardless of which container they’re in. Eg:
self.doggy_dropdowns = [self.paws_dd, self.ears_dd,... ]
for dd in self.doggy_dropdowns:
# do something
3 Likes