【问题标题】:How to set width of Treeview in tkinter of python如何在python的tkinter中设置Treeview的宽度
【发布时间】:2017-01-29 07:25:19
【问题描述】:

最近,我使用tkinter TreeView 来显示Python 中的许多列。具体来说,树视图中有 49 列数据。我使用grid 来管理我的小部件。

我发现树视图的宽度只取决于列的宽度。

我的问题是,如何设置 Treeview 的宽度。 (默认宽度是所有列的宽度之和)

当我所有的列宽都设置为 20 时。这是 49 列。 :)

这是我的主要代码:

frame = Frame(self.master, width = 1845, height = 670)
frame.place(x = 20, y = 310)
tree_view = Treeview(frame, height = 33, selectmode = "extended")
for i in range(len(id_list)):
    tree_view.column(id_list[i], width = width_list[i], anchor = CENTER)
    tree_view.heading(id_list[i] , text = text_list[i])
tree_view["show"] = "headings"
# Omit the declaration of scrollbar    
tree_view['yscroll'] = self.y_scollbar.set
tree_view['xscroll'] = self.x_scollbar.set
tree_view.grid(row = 0, column = 0, sticky = NSEW)
for item in detail_info_list:
    tree_view.insert("",0, text = str(item.id), value=(...))

id_list,width_list,text_list用于存储列信息。 detail_info_list 是存储Treeview中显示的数据。

我的目标是当我定义某个列的大宽度(例如:3000)时,我的树视图可以按我的预期显示数据。但是树视图在我的屏幕上,水平滚动条也不能滑动。

当第 17 列设置为 1500 时:

我看不到我的按钮,也无法滑动水平滚动条。

另外,我已经尝试了一些解决方案。

  • 定义一个框架作为 Treeview 父级。并定义宽度和高度来约束 Treeview。但它不起作用。
  • 我查阅了一些文档并搜索了这个问题。我没有找到任何将宽度设置为常数的解决方案。

【问题讨论】:

  • 如果列数和它们的宽度是固定的(它定义了 Treeview 的宽度),究竟是什么问题?
  • 请张贴代码,并告诉您想要的结果是什么。那么答案可以是具体的。
  • 你能发布完整的(工作)代码吗?
  • 我添加了关于 Treeview @JacobVlijm 的主要代码

标签: python tkinter treeview


【解决方案1】:

在尝试了很多方法来解决这个问题之后,我找到了一个简单但愚蠢的解决方案。初始化Treeview的宽度后,只需要调整列的大小,Treeview的宽度不会改变。

也许,这就是 Tcl/Tk 的约束。

【讨论】:

  • 您能详细解释一下吗?我已经看到初始列大小定义了树的小部件大小......但是之后如何调整列的大小?您的意思是在小部件已经布局之后以某种方式手动或通过代码调整它们的大小?
  • 没关系,只是想通了!您可以先在根Tk 对象上调用update()(这将完成所有布局),然后然后根据需要调整列的大小(在我的情况下,我使用measure 方法tkinter.font.Font).
  • @jdehesa 你能把代码贴出来吗,我不明白吗?
  • @AleksandarBeat 我有这样的东西view = ttk.Treeview(frame, columns=cols, show="headings"),所以首先我做for col in cols: view.column(col, width=0) 以获得“最小宽度”树,之后我运行root.update()root 是根 Tk 对象),强制树的布局并在窗口中固定其宽度,然后我使用 for col in cols: view.heading(col, text=col); view.column(col, width=col_width) 设置标题和实际宽度,其中 col_width 是所需的列宽(在我的case font.measure(col), font 被定义为tk.font.Font(root))。
【解决方案2】:

在搜索了一个多星期后,我偶然发现了一种非常简单的“魔术”方法。

  1. 我读取了主窗口的当前大小
  2. 将数据添加到树视图
  3. 根据条目的最大长度设置每列的宽度(使用measure
  4. 在我的 mainWindow 上调用 update 函数(不确定是否需要这样做)
  5. 将主窗口的大小设置为存储的值

这是我的代码:

def reloadTreeViewData(self):
    # get current size of main window
    curMainWindowHeight = self.parent.winfo_height()
    curMainWindowWidth = self.parent.winfo_width()

    #delete all
    for child in self.tree.get_children():
        self.dicData = {}
        self.tree.delete(child)

    # reload all
    count = 0
    for row in self.data:
        adding_string = []
        for element in self.indexlist:
            adding_string.append(str(row[element]))
        insert_ID = self.tree.insert('', 'end', text=count, values=adding_string)
        # save the data in it's original types in a dictionary
        self.dicData[insert_ID] = [row[x] for x in self.indexlist]
        count += 1

    # reset column width
    max_colum_widths = [0] * len(self.indexlist)
    for child in self.tree.get_children():
        rowData = self.dicData[child]
        for idx, rowIdx in enumerate(self.indexlist):
            item = rowData[idx]
            new_length = self.myFont.measure(str(item))
            if new_length > max_colum_widths[idx]:
                max_colum_widths[idx] = new_length
    for idx, item in enumerate(self.attributeList):
        if int(max_colum_widths[idx]) < 50:
            self.tree.column(item, width=50)
        else:
            self.tree.column(item, width=int(max_colum_widths[idx]))

    # restore the size of the mainWindow
    self.parent.update()
    self.parent.geometry("" + str(curMainWindowWidth) + "x" + str(curMainWindowHeight))

我的树视图标题存储在self.attributeList 中,但数据来自数据库,该数据库有更多我想显示的列。所以我使用了一个映射列表,它存储为self.indexlist

self.myFont定义如下:

    import tkinter.font as tkFont
    self.myFont = tkFont.Font(self, "Calibri", 12)

我使用树视图只是为了显示数据和一个单独的字典来保存数据,使用子 ID(由insert 返回)作为键。这样我就可以保留插入到 treeView 中的真实数据。这对于像 '0005' 这样的字符串很重要,当您从树视图中调用它并丢失前导零时,它将返回 5(整数)。

我希望此解决方案对其他人有所帮助。如果有更方便的解决方案,请随时发表评论。

如果您对我的代码有任何疑问,请随时提问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2018-07-04
    • 2010-10-15
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多