簡體   English   中英

tkinter ttk treeview 如何設置固定寬度? 為什么它隨列數而變化?

[英]tkinter ttk treeview how to set fixed width? why it change with number of column?

我正在嘗試使用 python tkinter 構建一個界面來顯示 Treeview 的數據庫表信息。標題是表架構,並將數據行插入到 treeview 表中。 由於不同表格的列數可能不一樣,所以我想自動調整列寬,使treeview表格的總寬度固定。 我在 Pycharm 2018.3-community 中編寫了 python3 代碼,並使用函數(顯示表)插入數據行並使用“treeview.column(col, width = int( total_width / len(cols)), minwidth=0, anchor ='center',stretch=0 )" 設置列寬。 顯示頁面時調用 function(我在調用時對該行添加注釋)。 第一次運行代碼時,列寬按寬度正常調整,表格總寬合適無誤,如下圖。 正常寬度

但是,如果我點擊一個按鈕調用相同的function插入相同的數據行,那么treeview的表格寬度就會改變。 我發現它隨着列數的變化而變化,如下所示。 我不知道為什么會這樣。 請指教。 非常感謝。 我的代碼附在底部。 改變寬度

class ListPage(tk.Tk):
table_list = sample.scan_result.table_list
table_index = 0

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent, bg='#C6E2FF')


    self.tbTitlelabel = tk.Button(self, text="Table", font=("Verdana", 18, "bold"), bg='#C6E2FF', fg='darkblue', command=lambda: controller.show_frame(start_page.StartPage))
    self.tbTitlelabel.grid(row=1, column=0, columnspan=1, padx=(150, 0), sticky='w')

    self.nextLabel = tk.Button(self, text="Next", font=("Verdana", 8, "bold"), bg='#C6E2FF', fg='darkblue',command=lambda:self.nextTable())
    self.nextLabel.grid(row=1, column=0, columnspan=1, padx=(280, 0), sticky='w')

    **# if call the function by the button, the table width change.** 
    self.preLabel = tk.Button(self, text="Previous", font=("Verdana", 18, "bold"), bg='#C6E2FF', fg='darkblue', command=lambda:self.showTable() )   
    self.preLabel.grid(row=1, column=0, columnspan=1, padx=(380, 0), sticky='w')

    style = ttk.Style()
    style.configure("Treeview.Heading", font=("Verdana", 15))
    self.tree = ttk.Treeview(self, height=10, show = 'headings', selectmode='browse')
    self.tree.grid(row=2, column=0, columnspan=1, padx=(120, 0), sticky='w')

    ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
    self.tree['yscroll'] = ysb.set
    ysb.grid(row=2, column=0, sticky='ens')

    **# if call the function during the page intial, the table width is good.** 
    self.showTable()  


def nextTable(self):
    if self.table_index < len(self.table_list)-1:
        self.table_index += 1
    self.showTable()

def previousTable(self):
    if self.table_index > 0:
        self.table_index -= 1
    self.showTable()

def showTable(self):
    print('run show table')
    col_start_pos = 0

    for i in self.tree.get_children():
        self.tree.delete(i)

    if len(self.table_list) > self.table_index:
        print(  self.table_index,  self.table_list)

        table_item = self.table_list[self.table_index]
        print(self.table_list[1], self.table_index)
        self.tbTitlelabel['text'] = table_item.db_name
        col_name = table_item.col_name[col_start_pos:]
        self.tree['columns'] = col_name
        data_list = table_item.data_list

        for col in col_name:
            self.tree.heading(col, text=col)
            **self.tree.column(col, width= int(600 / len(col_name)), minwidth=0, anchor='center',stretch=0) # auto adjust column width**

        x=0
        while x < 7:
            for list in data_list:
                self.tree.insert('', 'end', values = list[col_start_pos:] )
            x+=1

經過多次嘗試,我自己找到了解決方案。 我把它放在下面以防有人遇到同樣的問題。 就像我之前說的,第一次生成treeview表時,表的width是正確的。 所以,每次當我們需要展示一張表格時,我們需要銷毀舊的treeview.destory() ,然后創建一個新的treeview ,然后插入數據。

在嘗試了 root.update()、treeview.update() 和 treeview.destroy() 之類的所有東西之后,我自己也遇到了同樣的問題,這弄亂了我所有的 gui。 最后通過在清除樹視圖之前將列的寬度保存在列表中來修復它,然后使用這些寬度與新的寬度進行比較並使用較大的...

columns = []
wcols = []
row = 1
for each in self.table_tree.get_children():
    if row > 1: break
    columns = list(self.table_tree.item(each, option='values'))
    print(columns)
    for i in range(len(columns)):
        wcols.append(self.table_tree.column(i, width=None))
    row = row + 1

然后后來

self.table_tree["columns"]=column_names
indx = 0
h_col_w = []
new_col_w = []
for i in column_names:
    h_col_w.append(tkFont.Font().measure(i))
    if not(wcols == []):
        if h_col_w[indx] < wcols[indx]:
            h_col_w[indx] = wcols[indx]
    self.table_tree.column(i, width=h_col_w[indx], stretch=True) ;"set the width of the column to the width of the column name"
        self.table_tree.heading(i, text=i, command= lambda _col=i: \
                                self.treeview_sort_column(self.table_tree, _col, True))
        indx = indx + 1

我在刷新樹時這樣做:

self.geometry(self.winfo_geometry())

其中“自我”是樹的主人。 當我通過 tree.config(columns=new_columns) 在樹上添加新列時,樹將調整自身大小,但不會使用上述命令調整大小。 該命令可以放在配置之前或之后。 但是很抱歉我不知道原因。

我知道這是一個舊線程,但我最近遇到了類似的問題,更新選項不起作用,並且無法選擇銷毀。 這個決議對我來說很簡單。 一旦我將show = 'headings'移動到對列寬進行所有最終調整后,一切都會正確顯示。 如果init方法中的行,我無法運行我期望的 OP 代碼:

self.tree = ttk.Treeview(self, height=10, show = 'headings', selectmode='browse')

替換為:

self.tree = ttk.Treeview(self, height=10, selectmode='browse')

並將以下內容添加到 showTable 方法的末尾:

self.tree['show'] = 'headings'

那么它應該渲染得很好。

由於我的聲望點,我不能發表簡單的評論。 因此,我將對此進行一些擴展。

我在刷新數據時遇到了同樣的樹大小調整問題。

對我來說, user16129445 (見上文)的答案變體非常有效。 我定義了self.tree['show']選項以在刷新樹后保持列寬固定。

在我的例子中,我還有一個樹列(即第 0 列),在這種情況下您要使用該選項:

self.tree['show'] = 'tree'

代替

self.tree['show'] = 'headings'

效果很好,但隱藏了樹列; 或者您也可以使用以下組合,如果您希望列 #0 和標題都顯示:

self.tree['show'] = ['tree', 'headings']

也許值得一提的是,我還有一個隱藏的列,在列的自動調整后顯示:

widths = (200, 300, 300)
self.tree.column("#0", width=widths[0], minwidth=widths[0])  # tree column
self.tree.column("key", width=0, minwidth=0)  # hidden
self.tree.column("name", anchor=tk.W, width=widths[1])
self.tree.column("value", anchor=tk.W, width=widths[2])

我可以通過使用以下選項指示要顯示的列來強制"key"列保持隱藏狀態:

self.tree["displaycolumns"] = ('name', 'value')

我使用可變widths來定義樹初始化時的列寬,這些在刷新后保持不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM