10

我正在尝试在 Python 中开发 GTK 应用程序,但我真的坚持正确使用gtk.TreeStore. 我的主要问题:我已经解析了一些 JSON,并且我有自己的数据结构,它基本上是一个 Python 列表和两种对象:一种表示项目集合(集合不能嵌套),另一种表示项目(它可能出现在列表中以及集合中)。

我已经熟悉 a 的基本用法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. 文档中的链接直接指向本段:

一个数值,表示已注册类型的唯一标识符。

我对该主题的研究到此结束,谷歌发现大部分是 GTK 2.x 教程,除了等之外,没有关于插入其他数据类型str的内容int
问题:

  • 是否可以实现新的 GType(或任何其他可以在树存储中插入自定义数据的接口)以及如何实现?
    我已经尝试过,GObject但没有帮助。

  • 如何摆脱同时保留两个数据结构?
    即我的解析结果和 Treestore 中的重复信息。

  • 如何处理混合内容?
    就我而言,我有具有不同附加信息的集合和项目(在树视图中镜像为有或没有子节点的节点)。

如果上述问题解决了,我在处理选择时也摆脱了这个问题:很难匹配一个简单的类型str或者int匹配我之前插入的一个项目。这样的属性必须是一个键,你仍然会用解析结果搜索列表,这是无效的。

先感谢您!

与问题没有直接关系的其他信息:


TreeModel在我阅读GTK 2 教程之前,我认为实现自定义可能是一个可行的挑战:

然而,所有这些都是有代价的:你不可能在不到一千行的时间内编写一个有用的自定义模型,除非你去掉所有的换行符。编写自定义模型并不像听起来那么困难,而且值得付出努力,尤其是因为如果您有大量数据需要跟踪,它会产生更清晰的代码。

这仍然有效吗?


我刚刚遇到http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm这有帮助吗?与 PyGTK 2.0 一样多的资源。已弃用。

4

1 回答 1

16

问题解决了!对于遇到同样问题的其他人,我将收集一些有用的资源和我的示例代码。如果你知道怎么做也没关系,但它真的没有记录在案。

完整的示例代码,用于让 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()
于 2012-06-24T19:35:45.740 回答