Показать раскрывающийся список без записи с помощью PyGObject ComboBox

На самом деле, у меня есть список (fooId, fooName), и мне нужно показать раскрывающийся список, в котором отображается только fooName из этого списка. Но когда мне нужно получить выбранный элемент от пользователя, я просто хочу получить fooId, а не fooName.

Согласно документации, я сейчас делаю это:

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)

Как вы можете себе представить, эти строки работают правильно, за исключением того, что ComboBox показывает запись с раскрывающимся списком. Мне не нужна эта запись, поэтому я попытался использовать:

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

Но теперь мой выпадающий список пуст.

Любая идея?


person gaetanm    schedule 07.05.2013    source источник


Ответы (1)


Я понимаю вашу проблему. Вам нужно создать CellRendererText следующим образом:

#-*- 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()

Когда вы создаете ComboBox с Entry, ComboBox предполагает конфигурацию рендерера для вашей модели, потому что предполагается, что вы в конце концов получите строку, она может быть введена пользователем или выбрана пользователем, но в конце вы позаботьтесь об этой строке, поэтому ваша модель будет «плоской» только с одним столбцом. В большинстве случаев это так, за исключением случаев, когда вы используете запись для выполнения автоматического поиска, но для этого есть специальная настройка, специальные связанные объекты и более продвинутые возможности.

Если вы создаете ComboBox без Entry, вам необходимо определить соответствие между вашей моделью и презентацией. Для этого существует несколько видов рендереров: CellRendererPixbuf, CellRendererText, gtk.CellRendererToggle, CellRendererSpinner и т.д.

Каждый Renderer будет иметь набор атрибутов, которые вы можете сопоставить со столбцами в вашей модели. В приведенном выше примере я помещаю объект CellRendererText в ComboBox, у которого есть атрибут «текст» (тот, который отображается в раскрывающемся списке), сопоставленный со столбцом модели 1.

Вот тот же пример, но с большим количеством атрибутов, в данном случае с цветом текста:

#-*- 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()
person Havok    schedule 07.05.2013
comment
Большое тебе спасибо! Ваше объяснение идеально! :D - person gaetanm; 07.05.2013