sorting the treeview tkinter column without clicking on the column header

Question:

I am writing a program where there is a customer record log. The program has the ability to enter the time and the client. This data is stored in the database. I can’t sort the time without clicking on the column header. I wanted that when entering the time and the name of the client, and clicking on the save button, the time was sorted. I get the time, sort it, but the move() method does not move the elements to the positions I need.

This is part of the code. In the sort_time() method, I’m trying to sort the time.

import tkinter as tk
from tkinter import ttk
from tkinter import *
import time
from datetime import datetime

class Main(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.create_calendar()
        self.create_journal()
        self.create_button()

    def create_calendar(self):
        self.journal_frame = tk.Frame(self, borderwidth=1, 
             highlightthickness=5, highlightbackground='red')
        self.journal_frame.grid(row=0, column=0, sticky='ns')
        self.button_frame = tk.Frame(self, borderwidth=1, 
             highlightthickness=5, highlightbackground='red')
        self.button_frame.grid(row=1, column=0)

    def insert(self):
        self.tree.insert('', END, values=(self.c_time.get(), 
                          self.e_fio.get()))

    def sort_time(self):
        time = [(self.tree.set(i,0), i) for i in 
                       self.tree.get_children('')]
        spisok_time = [time[x][0] for x in range(len(time))]
        sorted_spisok = sorted(spisok_time, key=lambda y: 
                          datetime.strptime(y, '%H:%M'))
        spisok_new_time = [(sorted_spisok[z], str(z+1)) for z in 
                            range(len(sorted_spisok))]
        for index, (val, k) in enumerate(spisok_new_time):
            self.tree.move(k, '', index)

    def create_journal(self):
        columns = ('time', 'client')
        self.tree = ttk.Treeview(self.journal_frame, columns=columns, 
                                  show='headings')
        self.tree.grid(row=0,column=0)
        self.tree.heading('time', text='Time', anchor='center')
        self.tree.heading('client', text='Client', anchor='center')
        self.tree.column('#1', width=50, stretch=True, anchor='e')
        self.tree.column('#2', width=250, stretch=False, 
                            anchor='center')

    def create_button(self):
        self.b_sort = tk.Button(self.journal_frame, text='Sort', 
                                 command=self.sort_time)
        self.b_sort.grid(row=1, column=3, sticky='e')
        self.l_time = tk.Label(self.button_frame, text='Time:')
        self.l_time.grid(row=0, column=0, sticky='w')
        time = ['8:00', '8:30', '9:00', '9:30', '10:00', '10:30', 
                 '11:00', '11:30',
                 '12:00', '12:30', '13:00', '13:30', '14:00', 
                  '14:30', '15:00', '15:30',
              '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', 
                 '19:00', '19:30']
        self.c_time = ttk.Combobox(self.button_frame, values=time, 
                                     width=5)
        self.c_time.grid(row=0, column=1)
        self.l_fio = tk.Label(self.button_frame, text='Name:')
        self.l_fio.grid(row=1, column=0, sticky='w')
        self.e_fio = tk.Entry(self.button_frame, width=20)
        self.e_fio.grid(row=1, column=1)
        self.b_save = tk.Button(self.button_frame, text='Save', 
                                 command=self.insert)
        self.b_save.grid(row=5, column=1, sticky='e')

if __name__ == '__main__':
    root = tk.Tk()
    win = Main(root)
    win.pack()
    root.title('Вывод данных')
    root.geometry('1500x800+100+100')
    root.mainloop()
Asked By: NikV

||

Answers:

In the sort_time(), you sorted only timestamps into the sorted_spisok, lost the information on the order of item identifiers, and put arbitrary identifiers into the spisok_new_time.

So, sort the entire rows including item identifiers like this.

...
    def sort_time(self):
        rows = [(self.tree.set(i,0), i) for i in 
                       self.tree.get_children('')]
        sorted_rows = sorted(rows, key=lambda row: 
                          datetime.strptime(row[0], '%H:%M'))
        for index, (_, id) in enumerate(sorted_rows):
            self.tree.move(id, '', index)
...
Answered By: relent95
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.