Показать раскрывающийся список без записи с помощью 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)

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

Любая идея?

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, у которого есть атрибут text (тот, который отображается в раскрывающемся списке), сопоставленный со столбцом модели 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()
Другие вопросы по тегам