我正在尝试使用python tkinter构建一个接口,以使用Treeview显示数据库表信息。标题是表模式,并将数据行插入到树视图表中。由于不同表中的列数可能不一样,我想自动调整列的宽度,以便修复树视图表的总宽度。我在Pycharm 2018.3-community中编写了python3代码,并使用了一个函数(show table)来插入数据行并使用了“treeview.column(col,width = int(total_width / len(cols)),minwidth = 0,anchor ='center',stretch = 0)“设置列宽。显示页面时调用该函数(我在调用时为该行添加注释)。当代码第一次运行时,列宽通常按宽度调整,总表宽度非常合适且正确,如下所示。
但是,如果我单击一个按钮来调用相同的函数来插入相同的数据行,那么树视图表的宽度将会改变。我发现它随着列数的变化而变化,如下所示。我不知道为什么会这样。请指教。非常感谢 !我的代码附在底部。
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.destory()),然后创建一个新的树视图,然后插入数据。
在尝试了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)在其上添加新列时,树将自行调整大小,但不会使用上面的命令调整大小。该命令可以放在配置之前或之后。但对不起,我不知道原因。