我正在尝试用Python开发一个GTK应用程序,而且我真的坚持使用gtk.TreeStore
的正确用法。我的主要问题:我已经解析了一些JSON,我有自己的数据结构,它基本上是一个Python列表和两种对象:一个表示项目集合(集合不能嵌套)和一个表示项目(它可能出现在列表和集合中。)
我已经熟悉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.x教程,而不是插入除str
和int
等其他数据类型的内容。
问题:
是否可以实现新的GType(或任何其他可以在树库中插入自定义数据的接口)以及如何操作?
我已经尝试从GObject
派生,但没有帮助。
如何摆脱同时保留两个数据结构? 即我的解析结果和Treestore中的重复信息。
如何处理混合内容? 在我的情况下,我有不同附加信息的集合和项目(在树视图中镜像为带或不带子项的节点)。
如果上述问题得到解决,我在处理选择时也会解决问题:很难匹配像str
或int
这样的简单类型来匹配之前插入的项目。这样的属性必须是一个密钥,你仍然可以使用已解析的结果搜索列表,但这种结果无效。
提前谢谢!
与问题没有直接关系的其他信息:
我认为实施自定义TreeModel
可能是一个可行的挑战,直到我在tutorial for GTK 2中看到这一点:
但是,所有这些都需要付出代价:除非您删除所有换行符,否则不太可能在不到一千行中编写有用的自定义模型。编写自定义模型并不像听起来那么困难,并且它可能值得付出努力,尤其是因为如果您需要跟踪大量数据,它将导致更加安全的代码。
这仍然有效吗?
我刚遇到http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm这有用吗?对于PyGTK 2.0来说,很多都是资源。已弃用。
答案 0 :(得分:13)
问题解决了!对于遇到同样问题的其他人,我会堆积一些有用的资源和我的示例代码。如果你知道怎么做就没关系,但它确实没有记录。
正确地从具有属性的GObject
派生:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/objects.html
如何欺骗TreeView接受CellRendererText
的自定义值,包括实现传递给set_cell_data_func
的函数的有用代码段(需要针对TreeView
进行调整)
How to make GtkListStore store object attribute in a row?
TreeView上的一般好文档
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()