Setting dropdown.selected_value programmatically

What I’m trying to do:

I have a dropdown box which is displaying values from a given list that has been set earlier. I then need to be able to access the selected_value later as the object rather than the tuple.

Code Sample:

class A:
    def __init__(self, name=""):
        self.name = name
    def do_something(self):
        pass

list = [A('first'), A('second'), A('third')]
dropdown.items = [(listitem.name, listitem) for listitem in list]

def set_dropdown_value(dropdown, list_index):
    dropdown.selected_value = list[list_index]

set_dropdown_value(dropdown, 1)
...
if dropdown.selected_value is not None:
    dropdown.selected_value.do_something()

If I do this, the dropdown box shows <Invalid Value> when I launch the app.

What I’ve tried and what’s not working:

I have also tried this version:

def set_dropdown_value(dropdown, list_index):
    dropdown.selected_value = (list[list_index].name, list[list_index])

This also shows <Invalid Value> when I launch the app. And also, when I try to access dropdown.selected_value later in code, it still contains a tuple, which means I cannot call do_something() on that object.

Note: If I select the value in the app’s UI, everything works correctly. It’s only when trying to set dropdown.selected_value programmatically that it misbehaves.

How do I set the dropdown’s value so that it shows the name of object A in the UI while also returning the full object A() in selected_value?

Thanks!

Welcome to the forum!

It’s hard to tell the scope of everything from your example, but when I put this code into a form with a dropdown, it works fine:

    def __init__(self, **properties):
        # Set Form properties and Data Bindings.
        self.init_components(**properties)

        alist = [A('first'), A('second'), A('third')]
        self.drop_down_1.items = [(listitem.name, listitem) for listitem in alist]
        self.drop_down_1.selected_value = alist[1]

So there’s nothing wrong with the approach you’re trying to use, it’s got to be something else. Do you have a clone you can share with the actual form that’s having trouble?

1 Like

Hm, it might be because I’m actually using setattr, which I assumed would be equivalent to the = operator:

def set_dropdown_value(uielement, property_name, list_index):
    setattr(uielement, property_name, list[list_index])

set_dropdown_value(dropdown, 'selected_value', 1)

Aha! I finally figured it out. The object that I was setting to dropdown.selected_value was identical but not exactly the same object as the one that was in dropdown.items. So I was effectively doing this:

self.alist = [A('first'), A('second'), A('third')]
self.drop_down_1.items = [(listitem.name, listitem) for listitem in self.alist]
self.drop_down_1.selected_value = A('second')

Thanks for the help. Hopefully, this helps anyone who is running into this issue in the future.

Edit: Overriding __eq__() on class A to test for equality fixes the issue.

1 Like

A word of caution about assignments like these:

In general, please don’t redefine the built-in list type, or the name of any built-in Python type/function/object/whatever. It will come back to bite you later, in the form of confusion and bugs. Another name would serve you just as well, and would not cause problems.

2 Likes