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