如何在python的tkinter中设置Treeview的宽度

新手上路,请多包涵

最近,我使用 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。但它没有用。
  • 我查阅了一些文件并搜索了这个问题。我找不到任何将宽度设置为常数的解决方案。

原文由 ddming000 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.3k
1 个回答

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

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

这是我的代码:

 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))

我的 treeView 标题存储在 self.attributeList 但数据来自数据库,其中有更多列我想显示。所以我使用存储为 self.indexlist 的映射列表。

self.myFont 定义如下:

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

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

我希望这个解决方案可以帮助其他人。如果有更方便的解决方案,请随时发表评论。

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

原文由 Krossi 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏