jonny
jonny

Reputation: 4663

Get active item of Gtk ComboBox after searching

I created a Gtk.ComboBox in PyGTK with an entry completion using the following code:

completer = Gtk.EntryCompletion()
completer.set_model(combo.get_model())
completer.set_text_column(0)
combo.get_child().set_completion(completer)

I do have a few items (>400), so scrolling through the combobox looking for a specific one is rather tedious. But when I use the entry to input text, search for items and then select an item, calling get_active() in response to the changed signal returns -1...? It works as expected when scrolling to the item without searching and then selecting it.

I can get the text in the entry by using combo.get_child().get_text() but I can't search the model because every entry may appear several items.

How can I search for text, select an item, and then get the selected row of the original model?

#!/usr/bin/python
from gi.repository import Gtk

class MyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self)
        self.add_combo()

    def add_combo(self):
        store = Gtk.ListStore(str)
        combo = Gtk.ComboBox(model=store, has_entry=True)
        combo.set_entry_text_column(0)
        store.append(('Hello',))
        store.append(('World',))

        completer = Gtk.EntryCompletion()
        completer.set_model(combo.get_model())
        completer.set_text_column(0)
        combo.get_child().set_completion(completer)

        combo.connect('changed', self.changed)

        self.add(combo)

    def changed(self, combo):
        print 'active', combo.get_active()

win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

To reproduce: Type W in the entry, select World, get active -1, where I would expect active 1.

Upvotes: 0

Views: 2180

Answers (1)

Jussi Kukkonen
Jussi Kukkonen

Reputation: 14577

The completion doesn't know about the combo (and combo doesn't know about the completion) so it can't update the active value. I think this should do it:

# in initialization:
completer.connect("match-selected", self.match_selected)
self.combo = combo

def match_selected(self, completion, model, iter):
    self.combo.set_active_iter (iter)

That said, this still doesn't cover the possibility of someone just writing a matching string...

Upvotes: 1

Related Questions