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

时间:2016-09-21 07:19:11

标签: python tkinter treeview

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

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

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

当我的所有列宽都设置为20.这是49列。 :) enter image description here

这是我的主要代码:

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_listwidth_listtext_list用于存储列信息。 detail_info_list用于存储Treeview中显示的数据。

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

当第17列设置为1500时: enter image description here

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

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

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

2 个答案:

答案 0 :(得分:1)

现在搜索了一周以后,我偶然发现了一种非常简单的方法来做“魔术”。

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

    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(整数)。

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

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

答案 1 :(得分:0)

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

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