tkinter ttk treeview, как установить фиксированную ширину?почему это меняется с номером столбца? - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь использовать python tkinter для создания интерфейса для отображения информации таблицы базы данных с помощью Treeview.Заголовок представляет собой схему таблицы и вставляет строку данных в таблицу древовидной структуры.Поскольку количество столбцов в разных таблицах может не совпадать, я хочу автоматически настроить ширину столбца, чтобы общая ширина таблицы в виде дерева была фиксированной.Я написал код python3 в сообществе Pycharm 2018.3 и использовал функцию (показать таблицу) для вставки строк данных и использовал "treeview.column (col, width = int (total_width / len (cols))", minwidth = 0, якорь= 'center', stretch = 0) ", чтобы установить ширину столбца.функция вызывается при показе страницы (я ставлю комментарий к строке при ее вызове).Когда код был запущен в первый раз, ширина столбца обычно корректировалась на ширину, а общая ширина таблицы хорошо подходила и корректна, как показано ниже.normal width

Однако, если я нажму кнопку для вызова той же функции и вставки той же строки данных, ширина таблицы древовидной структуры изменится.и я обнаружил, что это меняется с номером столбца, как показано ниже.Я не знаю, почему это произошло так.Пожалуйста, порекомендуйте.Большое спасибо !мой код прикреплен внизу.changed width

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

Ответы [ 3 ]

0 голосов
/ 12 марта 2019

У меня возникла та же проблема, после того, как я попробовал все, например root.update (), treeview.update () и treeview.destroy (), которые испортили весь мой графический интерфейс.Наконец исправили это, просто сохранив ширину столбцов в списке, прежде чем очистить древовидное представление, а затем использовать эту ширину для сравнения с новыми и использовать большее ...

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
0 голосов
/ 28 июля 2019

Я делаю это, когда обновляю дерево:

self.geometry(self.winfo_geometry())

, которое 'я' является хозяином дерева.Дерево изменит свой размер, когда я добавлю в него новый столбец посредством tree.config (columns = new_columns), но оно не изменится с помощью приведенной выше команды.Команду можно разместить до или после конфига.Но извините, что я не знаю причину.

0 голосов
/ 02 декабря 2018

после нескольких попыток я сам нашел решение.Я приведу это ниже на случай, если кто-то столкнется с той же проблемой.Как я уже говорил ранее, при первом создании таблицы древовидной структуры ширина таблицы будет правильной.и поэтому каждый раз, когда нам нужно показать таблицу, нам нужно уничтожить старую (treeview.destory ()), затем создать новое древовидное представление и затем вставить данные.

...