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 ответов


проблема решена! Для других людей, столкнувшихся с той же проблемой, я соберу несколько полезных ресурсов и мой пример кода. Это нормально, если вы знаете, как это сделать, но это нигде документально.

полный пример кода для заполнения 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()