使用单个自定义类型的GtkListStore和多列的GtkTreeView(Python中)

7 投票
1 回答
2457 浏览
提问于 2025-04-18 01:06

我想在一个 Gtk.TreeView 里显示一个对象的不同属性,假设我有这样的对象:

class MyClass(GObject.GObject):
    def __init__(self, first, last, age):
        self.first = first
        self.last = last
        self.age = age

然后我想把这些对象的实例存储在一个 Gtk.ListStore 里,如下所示。

store = Gtk.ListStore(MyClass)

现在,当我创建 Gtk.TreeView 的时候,我不知道怎么指定要显示两个列,一个是 first 属性,另一个是 age 属性。

view = Gtk.TreeView(model=store)
# Columns for first and age added here
...

这些帖子 (1)(2) 有点解释了如何使用自定义类型,但只用了一个列(这样 store 中的列数和 view 中的列数是一样的)。我觉得我想做的事情应该是很常见的,不需要什么特别的解决办法。也许是需要对 Gtk.ListStore 进行子类化,让它告诉 view 它有多个列,以及如何获取每个值?

另外,我该怎么做才能让 store 中的 MyClass 实例的变化自动通知并反映在 view 上呢?

1 个回答

7

你需要做两件事:首先,创建一个 ListStore,里面有一个类型为 TYPE_PYOBJECT 的列;然后,在树形视图的列上使用 set_cell_data_func,这样就可以根据相应对象的属性来设置单元格的文本。

下面是一个示例,展示了这个过程:

from gi.repository import Gtk, GObject

class MyClass(object):
    def __init__(self, first, last, age):
        self.first = first
        self.last = last
        self.age = age

tree_store = Gtk.ListStore(GObject.TYPE_PYOBJECT)
tree_store.append([MyClass("foo", "bar", 15)])
tree_store.append([MyClass("baz", "qux", 100)])

def make_column(caption, getter):
    rend = Gtk.CellRendererText()
    col = Gtk.TreeViewColumn(caption, rend)
    def _set_cell_text(column, cell, model, it, ignored):
        obj = model.get_value(it, 0)
        cell.set_property('text', getter(obj))
    col.set_cell_data_func(rend, _set_cell_text)
    return col

view = Gtk.TreeView(tree_store)
view.append_column(make_column("First", lambda obj: obj.first))
view.append_column(make_column("Last", lambda obj: obj.last))
view.append_column(make_column("Age", lambda obj: '%d' % obj.age))

w = Gtk.Window()
w.add(view)
w.show_all()
Gtk.main()

撰写回答