Setting up search entry in GtkDropDown

Hi,

I am wondering if someone here could help me understand how to set up a GtkExpression in a UI definition file. The GtkExpression is bound to the expression property of a GtkDropDown that also has its enable-search property set to true. All I would like is that, when I start typing in the search bar, only items that start and/or match the string I am typing be displayed in the GtkDropDown. My understanding is that I need to access the string property of the objects stored in the GtkStringList, which corresponds to the model property of the GtkDropDown. However, I have no idea how to actually provide these objects to the lookup element. Yet, the documentation mentions the following, which puzzles me:

GtkDropDown knows how to obtain strings from the items in a GtkStringList; for other models, you have to provide an expression to find the strings via gtk_drop_down_set_expression().

I paste my Python method below. Any help is gladly appreciated.

    @staticmethod
    def create_drop_down(strings):
        item_strings_ui = "\n".ljust(11).join(
            [f"<item>{string}</item>" for string in strings]
        )
        drop_down_ui_string = f"""<interface>
  <object class="GtkDropDown" id="drop-down">
    <property name="margin_start">100</property>
    <property name="margin_end">100</property>
    <property name="model">
      <object class="GtkStringList" id="string-list">
        <items>
          {item_strings_ui}
        </items>
      </object>
    </property>
    <property name="enable-search">true</property>
    <binding name="expression">
      <lookup type="GtkStringObject" name="string"></lookup>
    </binding>
  </object>
</interface>"""
        builder = Gtk.Builder.new_from_string(drop_down_ui_string, -1)
        return builder.get_object("drop-down")

It looks like I have managed to make it work. My updated method now looks like this:

    def create_drop_down(self, string_list, selected_item_string=None):
        string_list_items = "\n".ljust(11).join(
            [f"<item>{string}</item>" for string in string_list]
        )

        drop_down_ui_string = f"""<interface>
  <object class="GtkDropDown" id="drop-down">
    <property name="margin_start">100</property>
    <property name="margin_end">100</property>
    <property name="model">
      <object class="GtkStringList" id="string-list">
        <items>
          {string_list_items}
        </items>
      </object>
    </property>
    <property name="enable-search">true</property>
    <property name="expression">
      <lookup type="GtkStringObject" name="string"></lookup>
    </property>
  </object>
</interface>"""

        builder = Gtk.Builder.new_from_string(drop_down_ui_string, -1)
        drop_down = builder.get_object("drop-down")

        if selected_item_string is not None:
            drop_down.set_selected(string_list.index(selected_item_string))

        drop_down.connect("notify", self.drop_down_changed)

        return drop_down

However, there seem to be some problems. For example, while playing with the search, I encountered:

(python3:192359): Gtk-WARNING **: 16:42:40.881: FIXME: Handle the same item multiple times in the list.
Lars says this totally should not happen, but here we are.

Also, while scrolling through the entries of the GtkDropDown, I sometimes see:
(python3:192552): Gtk-WARNING **: 16:46:24.106: GtkListView failed to scroll to given position. Ignoring...

Finally, it looks like sometimes the GtkListItemFactory gets confused after selecting an item. What I mean is that opening the GtkDropDown again right after and selecting a displayed item actually picks another item as if the mapping from the widget to the model was corrupted or the graphical representation of the GtkDropDown was wrong. It seems to me this happens when selecting an item that has already been selected and only if the item is below the currently selected item in the graphical representation of the GtkDropDown.

This means you have duplicate objects in the model.

This is an issue internal to GTK, and the fix is in progress; you don’t have to do anything in your app.

1 Like

Hmm… That is odd because I am pretty sure I do not have duplicates given that I am using a Python set. I will see if I manage to reproduce.

Thank you for sharing this information.

@ebassi Can I ask you a slightly off-topic but still related question? Now that I have this search bar working in the GUI, how do I actually access it programmatically? In other words, given the GtkDropDown object, how do I obtain the reference to the search bar widget? This is useful, for example, to connect a controller or add something similar to a GtkEntryCompletion. I have searched the documentation and I have also looked through the methods/attributes of the PyGObject GtkDropDown but without success. Thank you for any help.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.