使用单个自定义类型的GtkListStore和多列的GtkTreeView(Python中)
我想在一个 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()