例如,让我们使用如下类创建一个 Treeview 小部件:
class FiltersTree:
def __init__(self, master, filters):
self.master = master
self.filters = filters
self.treeFrame = Frame(self.master)
self.treeFrame.pack()
self._create_treeview()
self._populate_root()
def _create_treeview(self):
self.dataCols = ['filter', 'attribute']
self.tree = ttk.Treeview(self.master, columns = self.dataCols, displaycolumns = '#all')
像往常一样填充根目录,插入子项。在代码块的末尾,您可以看到我想使用 Combo 对象将 Combobox 放置在树中的位置:
def _populate_root(self):
# a Filter object
for filter in self.filters:
top_node = self.tree.insert('', 'end', text=filter.name)
# a Field object
for field in filter.fields:
mid_node = self.tree.insert(top_node, 'end', text = field.name)
# insert field attributes
self.insert_children(mid_node, field)
def insert_children(self, parent, field):
name = self.tree.insert(parent, 'end', text = 'Field name:',
values = [field.name])
self.tree.insert(parent, 'end', text = 'Velocity: ',
values = [Combo(self)]) # <--- Combo object
...
接下来是 Combo 的类定义。按照我的理解,组合框小部件继承自 ttk 的 Labelframe 小部件,并且必须放置在 ttk 的 Labelframe 小部件内:
class Combo(ttk.Frame):
def __init__(self, master):
self.opts = ('opt1', 'opt2', 'etc')
self.comboFrame = ttk.Labelframe(master, text = 'Choose option')
self.comboFrame.pack()
self.combo = ttk.Combobox(comboFrame, values=self.opts, state='readonly')
self.combo.current(1)
self.combo.pack()
那么这是完全错误的吗?我希望能够在 Treeview 小部件内更改单位(例如米/秒、英尺/秒等)。
请问有什么建议吗?
树形视图小部件不支持嵌入小部件。
values
属性的值被视为字符串。
默认情况下,树视图是字符串列表森林的静态显示。 然而,通过工作,仔细阅读 Treeview 参考资料后,可以使 Treeview 具有相当的交互性。 对于这个问题,我将左键单击绑定到一个事件处理程序,该事件处理程序将鼠标 x,y 与单位属性单元格的边界框 (.bbox) 进行比较。 如果在框中,则直接在单位属性单元格的顶部显示一个用当前值(例如“flops”)初始化的组合框。
Tkinter.ttk 树视图参考 和 Tcl/tk 树视图参考
当然,将 Treeview 放在带有单独 Combobox 的框架中可能会更容易。
编辑:上面的覆盖答案假设有一个静态树视图和一个要覆盖的单元格。 更一般地说,使用identify_row来查看是否单击了某个项目。 如果是这样并且需要覆盖,请使用identify_column 来查看是否单击了相应的列。 如果是这样,请使用 bbox(item, col) 确定放置叠加层的位置。 叠加层不必是组合框。
或者,考虑在上面建议的框架或弹出窗口中使用单独的小部件。