GTK + 3.0: Как использовать Gtk.TreeStore с пользовательскими элементами модели?
Я пытаюсь разработать приложение GTK в Python, и я действительно застрял с правильным использованием gtk.TreeStore
. Моя основная проблема: я уже проанализировал некоторые JSON, и у меня есть собственная структура данных, которая в основном является списком Python и двумя видами объектов: один представляет коллекцию элементов (коллекции не могут быть вложены) и один для представления элементов (которые могут появиться в списке, а также в коллекции).
Я уже знаком с основами использования а TreeStore
и удалось получить элементы, правильно отображаемые на экране. Я не знаю, как справиться с тем, что treestore способен хранить только типы gobject (на данный момент я не уверен, потому что я мало знаю о системе типов gobject). В документации для C перечислены следующие (кроме PixBuf) основные типы, которые могут быть вставлены и автоматически сопоставлены с типами данных Python:
в качестве примера, gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_PIXBUF); создаст новый GtkTreeStore с тремя столбцами типа int, string и GdkPixbuf соответственно.
кроме того, он говорит, что вы можете вставить GType
. Ссылка из документации прямо указывает на этот абзац:
числовое значение, представляющее уникальный идентификатор зарегистрированного типа.
мое исследование темы заканчивается здесь, и Google находит в основном GTK 2.х учебники и ничего о вставке других типов данных, кроме str
и int
etc.
Вопросы:
можно ли реализовать новый GType (или любой другой интерфейс, который сделает возможным вставку пользовательских данных в treestore) и как это сделать?
Я уже пробовал выводить изGObject
но это не помогло.как я могу избавиться от учета двух структур данных одновременно?
А именно мой результат синтаксического анализа и дубликат информация в Treestore.как можно иметь дело со смешанным контентом?
В моем случае у меня есть коллекции и элементы с различной дополнительной информацией (которые отражаются в treeview как узлы с или без детей).
Если вышеуказанные вопросы разрешены, то я также получаю освобожданным проблемы регулируя выборы: трудно соответствовать простому типу как str
или int
чтобы соответствовать элементу, который я вставил раньше. Такой атрибут должен быть ключом, и все же вы должны искать список с проанализированными результатами, которые неэффективны.
спасибо заранее!
дополнительная информация, непосредственно не связанная с вопросом:
Я думал, что это может быть реальной проблемой для реализации пользовательского TreeModel
пока я не прочитал это в учебник для GTK 2:
однако, все это происходит по цене: вы вряд ли напишут полезная пользовательская модель менее чем в тысяче строк, если вы не удалите все символы новой строки. Написание пользовательской модели не так сложно, как может показаться, и это может стоить усилий, не в последнюю очередь потому, что это приведет к гораздо более разумному коду, если у вас есть много данных для отслеживания.
это все еще действует?
я только что наткнулся http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm может ли это быть полезным? Как много resoucres это для PyGTK основой 2.0. устаревшие.
1 ответов
проблема решена! Для других людей, столкнувшихся с той же проблемой, я соберу несколько полезных ресурсов и мой пример кода. Это нормально, если вы знаете, как это сделать, но это нигде документально.
правильно, вытекающих из
GObject
С properties:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/objects.htmlкак обмануть TreeView в принятии пользовательских значений для
CellRendererText
, в том числе полезный фрагмент для реализации функции, переданной вset_cell_data_func
(необходимо адаптировать дляTreeView
)
как сделать атрибут объекта магазина GtkListStore в строке?общая хорошая документация на TreeViews
http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html
полный пример кода для заполнения TreeView людьми и печати выбранного человека на кнопки:
from gi.repository import Gtk
from gi.repository import GObject
class Person (GObject.GObject):
name = GObject.property(type=str)
age = GObject.property(type=int)
gender = GObject.property(type=bool, default=True)
def __init__(self):
GObject.GObject.__init__(self)
def __repr__(self):
s = None
if self.get_property("gender"): s = "m"
else: s = "f"
return "%s, %s, %i" % (self.get_property("name"), s, self.get_property("age"))
class MyApplication (Gtk.Window):
def __init__(self, *args, **kwargs):
Gtk.Window.__init__(self, *args, **kwargs)
self.set_title("Tree Display")
self.set_size_request(400, 400)
self.connect("destroy", Gtk.main_quit)
self.create_widgets()
self.insert_rows()
self.show_all()
def create_widgets(self):
self.treestore = Gtk.TreeStore(Person.__gtype__)
self.treeview = Gtk.TreeView()
self.treeview.set_model(self.treestore)
column = Gtk.TreeViewColumn("Person")
cell = Gtk.CellRendererText()
column.pack_start(cell, True)
column.set_cell_data_func(cell, self.get_name)
self.treeview.append_column(column)
vbox = Gtk.VBox()
self.add(vbox)
vbox.pack_start(self.treeview, True, True, 0)
button = Gtk.Button("Retrieve element")
button.connect("clicked", self.retrieve_element)
vbox.pack_start(button, False, False, 5)
def get_name(self, column, cell, model, iter, data):
cell.set_property('text', self.treestore.get_value(iter, 0).name)
def insert_rows(self):
for name, age, gender in [("Tom", 19, True), ("Anna", 35, False)]:
p = Person()
p.name = name
p.age = age
p.gender = gender
self.treestore.append(None, (p,))
def retrieve_element(self, widget):
model, treeiter = self.treeview.get_selection().get_selected()
if treeiter:
print "You selected", model[treeiter][0]
if __name__ == "__main__":
GObject.type_register(Person)
MyApplication()
Gtk.main()