Gtk.TreeViewColumn中使用多CellRenderer加载模型字段失败求助
问题原因分析与解决方案
你遇到的TreeView为空且出现Gtk Critical警告的问题,核心原因是CellRenderer的打包与属性绑定顺序搞反了。
为什么会出错?
Gtk的gtk_cell_area_attribute_connect(对应Python里的add_attribute()方法)要求目标CellRenderer已经被添加到TreeViewColumn的Cell Area中。你现在的代码是先调用add_attribute()绑定属性,再用pack_end()把Renderer加到列里——这时候Gtk在绑定属性时找不到对应的Renderer,就会抛出那个断言失败的警告,同时因为属性绑定没有生效,TreeView自然显示为空。
修正后的代码
只需要调整pack_end()和add_attribute()的顺序,先把Renderer打包到列中,再绑定属性:
#!/usr/bin/env python3 import random import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GLib class TreeView(Gtk.TreeView): def __init__(self): # model self.model = Gtk.ListStore.new([int, int]) for i in range(5): self.model.append([i, (i*10)]) # view Gtk.TreeView.__init__(self, self.model) col = Gtk.TreeViewColumn.new() col.set_title('two model fields') # 先打包Renderer到列中 self.rendererA = Gtk.CellRendererText() col.pack_end(self.rendererA, True) # 再绑定属性 col.add_attribute(self.rendererA, 'text', 0) self.rendererB = Gtk.CellRendererText() col.pack_end(self.rendererB, True) col.add_attribute(self.rendererB, 'text', 1) self.append_column(col) if __name__ == '__main__': win = Gtk.Window.new(0) win.view = TreeView() win.add(win.view) win.connect('destroy', Gtk.main_quit) win.show_all() Gtk.main()
更简洁的写法
另外,你可以使用Gtk.TreeViewColumn.new_with_attributes()方法,一次性完成列的创建、Renderer的添加和属性绑定,这样能从根源上避免顺序错误:
# 替换原来的列创建代码 col = Gtk.TreeViewColumn.new_with_attributes( 'two model fields', Gtk.CellRendererText(), text=0 ) # 再添加第二个Renderer rendererB = Gtk.CellRendererText() col.pack_end(rendererB, True) col.add_attribute(rendererB, 'text', 1)
这样修改后,警告会消失,TreeView也能正常显示两列数据啦。
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

