如何在PyGObject中用Gtk.TreeStore实现树形Gtk.ComboBox?
实现带层级缩进的Gtk.ComboBox
嘿,我懂你想要的树形缩进下拉选项效果!问题出在Gtk.ComboBox默认不会自动识别TreeStore的层级结构——它不像TreeView那样天生支持缩进显示。不过咱们只需要给CellRendererText加个动态缩进的逻辑就能搞定,具体看下面的修改:
核心原因
ComboBox的CellRendererText控件默认不会根据TreeStore里节点的层级自动调整缩进,所以得手动计算每个节点的深度,然后把这个深度映射成缩进像素值。
修改后的完整代码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk class MyWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) # The Model store = Gtk.TreeStore(int, str) # first item in the row is an internal ID that should not # be displayed in the combo box root_it = store.append(parent=None, row=[1, "Eins"]) store.append(parent=root_it, row=[2, "Zwei"]) store.append(parent=root_it, row=[3, "Drei"]) # The View combo = Gtk.ComboBox.new_with_model(store) renderer = Gtk.CellRendererText() combo.pack_start(renderer, False) combo.add_attribute(renderer, "text", 1) # 关键逻辑:动态设置每个选项的缩进 def update_indent(column, cell, model, tree_iter, user_data): # 获取当前节点的层级深度(根节点深度为0,子节点+1) depth = model.get_path(tree_iter).get_depth() # 每个层级缩进20像素,可根据视觉需求调整数值 cell.set_property("indent", depth * 20) # 将缩进逻辑绑定到渲染器 combo.set_cell_data_func(renderer, update_indent, None) box = Gtk.VBox() box.add(combo) self.add(box) if __name__ == '__main__': window = MyWindow() window.connect("destroy", Gtk.main_quit) # 补充关闭窗口退出主循环的逻辑 window.show_all() Gtk.main()
关键代码解释
update_indent函数:这个函数会在每个下拉选项渲染时被调用,通过model.get_path(tree_iter).get_depth()获取当前节点的层级深度,然后把深度乘以固定像素值(这里是20),设置给CellRendererText的indent属性。combo.set_cell_data_func:把自定义的缩进逻辑绑定到CellRendererText上,让ComboBox在渲染每个选项时自动应用缩进。
运行修改后的代码,你就能看到预期的树形缩进效果了:
- Eins(无缩进)
- Zwei(缩进20px)
- Drei(缩进20px)
如果想要更复杂的树形样式(比如带连接线),可能需要自定义CellRenderer,但单纯的层级缩进用这个方法就足够简洁高效啦~
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

