我想使用gtk Treeview显示两个层次的数据(使用gtk Treestore模型)
数据格式如下:
**First(parent)** level
col_a, col_b, col_c, col_d, col_e
val_a, val_b, val_c, val_d, val_e
**Second(child)** level
col_x, col_y, col_z
val_x, val_y, val_z
数据层次如下:
^{pr2}$下面的pygtk代码是我尝试过的(修改了gtk教程中的代码)
import pygtk
pygtk.require('2.0')
import gtk
data = [
[('val_a1', 'val_b1', 'val_c1', 'val_d1', 'val_e1'), ('val_x1', 'val_y1', 'val_z1'), ('val_x2', 'val_y2', 'val_z2')],
[('val_a2', 'val_b2', 'val_c2', 'val_d2', 'val_e2'), ('val_x3', 'val_y3', 'val_z3')],
[('val_a3', 'val_b3', 'val_c3', 'val_d3', 'val_e3')],
[('val_a4', 'val_b4', 'val_c4', 'val_d4', 'val_e4'), ('val_x4', 'val_y4', 'val_z4'), ('val_x5', 'val_y5', 'val_z5')],
]
class BasicTreeViewExample:
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Basic TreeView Example")
self.window.set_size_request(200, 200)
self.window.connect("delete_event", self.delete_event)
self.treestore = gtk.TreeStore(str, str, str, str, str)
for detail in data:
for index, elem in enumerate(detail):
if index == 0:
piter = self.treestore.append(None, elem)
else:
self.treestore.append(piter, elem)
self.treeview = gtk.TreeView(self.treestore)
for i in range(5):
tvcolumn = gtk.TreeViewColumn('Column %s' % (i))
self.treeview.append_column(tvcolumn)
cell = gtk.CellRendererText()
tvcolumn.pack_start(cell, True)
tvcolumn.add_attribute(cell, 'text', i)
self.window.add(self.treeview)
self.window.show_all()
def main():
gtk.main()
if __name__ == "__main__":
tvexample = BasicTreeViewExample()
main()
但是,我在尝试运行上述代码时遇到以下错误:
Traceback (most recent call last):
File "test.py", line 55, in <module>
tvexample = BasicTreeViewExample()
File "test.py", line 33, in __init__
self.treestore.append(piter, detail[index])
ValueError: row sequence has wrong length
所以我的问题是:
即在Treeview中,我希望看到如下输出:
col_a, col_b, col_c, col_d, col_e
> val_a1, val_b1, val_c1, val_d1, val_e1
col_x, col_y, col_z
val_x1, val_y1, val_z1
col_x, col_y, col_z
val_x2, val_y2, val_z2
col_a, col_b, col_c, col_d, col_e
> val_a2, val_b2, val_c2, val_s2, val_e2
col_x, col_y, col_z
val_x3, val_y3, val_z3
col_a, col_b, col_c, col_d, col_e
> val_a3, val_b3, val_c3, val_d3, val_e3
col_a, col_b, col_c, col_d, col_e
> val_a4, val_b4, val_c4, val_d4, val_e4
col_x, col_y, col_z
val_x4, val_y4, val_z4
col_x, col_y, col_z
val_x5, val_y5, val_z5
如果使用上面的任何方法都不可行,那么使用哪种方法可以实现?在
简短回答和介绍
如何向添加数据gtk.TreeStore公司在不同层次结构中有不同数量的列?在
简单:你不能。GtkListStore和GtkTreeStore都是用来保存的 数据作为表。列是用索引和数据以固定方式定义的 类型。ListStore和TreeStore之间的唯一区别是 TreeStore,行有层次结构。更糟糕的是,GtkTreeView小部件也 期望数据以表的形式存储,因为每一行都将无条件获取 单元格使用其列索引,并期望在那里找到一些内容。 除非您编写自己的小部件,but you probably don't want to (天哪,这个文件有16570行长…)。在
但是,如果您不能编写自己的widget,您仍然可以编写自己的widget 模型。这会给你一些灵活性。在
另外,是否可以在gtk.TreeStore公司?在
在TreeView中显示数据涉及两个组件:GtkTreeView本身, 它在树状结构中获取数据并显示它们。TreeView小部件没有 具有显示每行标题的功能。但也有一些诀窍 处理模型和视图之间的数据,这可能会导致所需的结果 效果,虽然可能不是那么好。在
基础知识
所以,TreeView希望在一个数据表上工作,我们不能改变它。 好 啊。但我们仍然可以欺骗它,让它认为数据是一个表,实际上 不是。。。让我们从视图开始。我们至少需要五列来显示 父母的资料。孩子们只能使用 这五个,所以这很好。在
请注意,模型的列并不总是映射到树视图中的列。 它们实际上映射到单元渲染器的某些属性。例如,您可以 在模型中有一列定义行的背景色, 或定义要显示的图标的列。视图中的列只是一种方式 对齐单元格渲染器组,可能在标题下。但在这里,让我们 假设所有的值都是文本,它们应该进入 自己的专栏。在
父母将使用全部五列,而子女将只使用第2、3列 和4。然后,我们将欺骗模型在数据没有返回空文本时返回一个空文本 可用于目标单元格。在
创建新的TreeModel
关于在PyGTK中实现自定义GtkTreeModel的一些解释是 在this tutorial中提供。 这是一个sample implementation of it:
结果是:
在单元格中伪造标题
现在让我们使用模型在每个单元格中添加某种类型的标题 所需的数据。Full code is here。在
^{pr2}$结果是:
{2美元^
使用}
set_cell_data_func
或{如果您设法将数据放入ListStore或TreeStore中,则 就是说你找到一个诀窍,让父母和孩子分享相同的金额 和列类型,则可以使用 GtkTreeCellDataFunc 或者是GtkTreeModelFilter。在
PyGTK文档提供了Cell Data Functions的示例 和Tree Model Filters。在
例如,使用这些概念添加列标题可能比 创建完全自定义模型。在
这是code using TreeCellDataFunc。 请注意数据输入是如何格式化的,以便子级和父级 相同数量的数据。这是能够使用GtkTreeStore的条件。在
gtktreemodelpilter导致了几乎相同的结果。结果是一样的 而不是在单元格中伪造标题(除了我忘记将标题设置为不可见):
我希望这对你有帮助,其他人也会有同样的问题!在
相关问题 更多 >
编程相关推荐