2016-09-21 25 views
1

最近,我使用tkinterTreeViewPython中顯示很多列。具體而言,樹視圖中的49列數據。我使用grid來管理我的小部件。如何在python的tkinter中設置Treeview的寬度

我發現treeview的寬度只取決於列的寬度。

我的問題是,我如何設置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。但它沒有奏效。
  • 我查找了一些文件並搜索這個問題。我沒有找到任何解決方案將寬度設置爲常數。
+1

如果列數和寬度是固定的(它定義了Treeview的寬度),那麼究竟是什麼問題? – Daneel

+1

請發佈代碼,並告訴你想要的結果是什麼。那麼答案可以是具體的。 –

+0

你能發佈完整的(工作)代碼嗎? –

回答

0

嘗試了很多方法來解決這個問題後,我找到了一個簡單但愚蠢的解決方案。在初始化Treeview的寬度後,您只需調整列的大小並且Treeview的寬度不會改變。

也許,這是Tcl/Tk的約束。

+0

您能否請詳細解釋一下這個問題?我已經看到,最初的列大小定義了樹的小部件大小......但是,如何調整列的大小?你的意思是你在手動或者代碼上調整了它們的大小之後,這些小部件已經佈置好了嗎? – jdehesa

+0

沒關係,只是想通了!你可以首先調用'Tk'對象的'update()'(它將完成所有的佈局),然後_then_根據需要調整列的大小(在我的例子中,我使用'tkinter.font的'measure'方法。 Font')。 – jdehesa

0

現在搜索了一個多星期後,我偶然發現了一個很簡單的方法去做'魔法'。

  1. 讀取我的主窗口的當前大小
  2. 的數據添加到TreeView
  3. 設置爲根據一個條目的最大長度的每個列的寬度(通過使用measure
  4. 調用在我的主窗口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)) 

我的TreeView的標題都存儲在self.attributeList,但數據來自一個數據庫,其中有辦法更多的​​列我想展示。所以我使用一個存儲爲self.indexlist的映射列表。

self.myFont定義如下:

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

我使用TreeView只是爲了顯示數據和一個單獨的字典來保存數據,使用兒童-ID(由insert返回)爲重點。這樣我就保留了我插入到treeView中的真實數據。這對於'0005'這樣的字符串很重要,當你從樹形視圖中調用它時,它將返回5(整數),並且你丟失了前導零。

我希望這個解決方案可以幫助他人。如果有更方便的解決方案隨時發表評論。

如果您對我的代碼有任何疑問,請隨時詢問。

相關問題