Frage

Actually, I have a list (fooId, fooName) and I need to show a drop-down list wich only shows fooName from this list. But, when I need to get the selected item from the user, I just want to get the fooId and not the fooName.

According to the documentation, I'm currently doing this:

someFoo = model.getSomeFoo()
foo_list = Gtk.ListStore(int, str)
for foo in someFoo:
    foo_list.append([foo[0], foor[1]])
self.cb = Gtk.ComboBox.new_with_model_and_entry(foo_list)
self.cb.set_entry_text_column(1)

As you can imagine, those lines doing right, except that the ComboBox shows an entry with the drop-down list. I don't need this entry, so I tried to use:

self.cb = Gtk.ComboBox.new_with_model(foo_list)

But now my drop-down list is empty.

Any idea?

War es hilfreich?

Lösung

I understand your problem. You need to create a CellRendererText like this:

#-*- coding: UTF-8 -*-
from gi.repository import Gtk

class App(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title='ComboBox Test')

        model = Gtk.ListStore(int, str)
        for i in [[1, 'One'], [2, 'Two'], [3, 'Three'], [4, 'Four']]:
            model.append(i)

        combo = Gtk.ComboBox.new_with_model(model)
        renderer = Gtk.CellRendererText()

        combo.set_active(0)
        combo.pack_start(renderer, True)
        combo.add_attribute(renderer, 'text', 1)
        combo.connect('changed', self._changed_cb)

        self.add(combo)

        # Variables
        self.combo = combo
        self.model = model

    def _changed_cb(self, widget, param=None):
        comboiter = self.combo.get_active_iter()
        if comboiter:
            print("Changed to {}".format(
                     self.model.get_value(comboiter, 0)
            ))
        else:
            print("Nothing selected!")

win = App()
win.connect('delete-event', Gtk.main_quit)
win.show_all()
Gtk.main()

When you create a ComboBox with Entry the ComboBox assumes a renderer configuration for your model because it assumes you will be getting a string after all, it can be user entered o user selected, but at the end you will be caring about that string, so, your model will be "flat" with only one column. That is true most of the times, an exception is when you're using the entry to perform auto-search, but for that there is an especial setup, special associated objects and is more advanced.

If you're creating a ComboBox without Entry you need to define the match between your model and your presentation. For this, there is several types of renderers: CellRendererPixbuf, CellRendererText, gtk.CellRendererToggle, CellRendererSpinner, etc.

Each Renderer will have a set of attributes that you can match with columns in your model. In the above example, I'm putting a CellRendererText object in the ComboBox that has it's 'text' attribute (the one that is displayed in the drop-down list) mapped to model column 1.

Here is the same example but playing with more attributes, in this case the color of the text:

#-*- coding: UTF-8 -*-
from gi.repository import Gtk

class App(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title='ComboBox Test')

        model = Gtk.ListStore(int, str, str)
        for i in [[1, 'One', '#FF0000'], [2, 'Two', '#00FF00'], [3, 'Three', '#0000FF'], [4, 'Four', '#FFFF00']]:
            model.append(i)

        combo = Gtk.ComboBox.new_with_model(model)
        renderer = Gtk.CellRendererText()

        combo.set_active(0)
        combo.pack_start(renderer, True)
        combo.add_attribute(renderer, 'text', 1)
        combo.add_attribute(renderer, 'foreground', 2)
        combo.connect('changed', self._changed_cb)

        self.add(combo)

    def _changed_cb(self, combo, param=None):
        comboiter = combo.get_active_iter()
        if comboiter:
            print("Changed to {}".format(
                     combo.get_model().get_value(comboiter, 0)
            ))
        else:
            print("Nothing selected!")

win = App()
win.connect('delete-event', Gtk.main_quit)
win.show_all()
Gtk.main()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top