Search code examples
pythonsortingbuttontkintertreeview

How to make a Treeview column header into a Button?


I am trying to improve the functionality of my GUI by adding buttons to the headings but can't find any examples or information on this one. Is there a way to make the headings into a clickable button in this example? The Treeview is going to be populated from a DB so, if I can get the buttons to work, it means I can order the display in a nicer way than having more buttons outside the "box".

import tkinter as tk
from tkinter import ttk

screen = tk.Tk() 
screen.title('This One')
screen.geometry('890x400')
style = ttk.Style()
style.theme_use("clam")
screen.grid_rowconfigure(1, weight=1)
screen.grid_columnconfigure(0, weight=1)

cols = ('TOKEN', 'F-500', 'F-250', 'F-100', 'F-24', 'POS','NEG')
box = ttk.Treeview(screen, columns=cols, show='headings')
for col in cols:
    box.heading(col, text=col)
    box.grid(row=1, column=0, columnspan=2,sticky='nsew')


box.column("TOKEN", width=95)
box.column("F-500", width=85, anchor='e')
box.column("F-250", width=85, anchor='e')
box.column("F-100", width=85, anchor='e')
box.column("F-24", width=85, anchor='e')
box.column("POS", width=75, anchor='center')
box.column("NEG", width=75, anchor='center')



closeButton = tk.Button(screen, text="Close", width=15, command=exit).grid(row=10, column=0)

screen.mainloop()

Solution

  • The heading od the Treeview already are buttons with the optional keyword command. To use this in a forloop you can use lambda an annoynmous function.

    import tkinter as tk
    from tkinter import ttk
    
    screen = tk.Tk() 
    screen.title('This One')
    screen.geometry('890x400')
    style = ttk.Style()
    style.theme_use("clam")
    screen.grid_rowconfigure(1, weight=1)
    screen.grid_columnconfigure(0, weight=1)
    
    cols = ('TOKEN', 'F-500', 'F-250', 'F-100', 'F-24', 'POS','NEG')
    box = ttk.Treeview(screen, columns=cols, show='headings')
    for col in cols:
        if col == 'TOKEN':
            box.heading(col, text=col, command =lambda: print('token'))
        box.grid(row=1, column=0, columnspan=2,sticky='nsew')
    
    
    box.column("TOKEN", width=95)
    box.column("F-500", width=85, anchor='e')
    box.column("F-250", width=85, anchor='e')
    box.column("F-100", width=85, anchor='e')
    box.column("F-24", width=85, anchor='e')
    box.column("POS", width=75, anchor='center')
    box.column("NEG", width=75, anchor='center')
    
    
    
    closeButton = tk.Button(screen, text="Close", width=15, command=exit).grid(row=10, column=0)
    
    screen.mainloop()
    

    without using lambda:

    def token():
        print('token')
    
    cols = ('TOKEN', 'F-500', 'F-250', 'F-100', 'F-24', 'POS','NEG')
    box = ttk.Treeview(screen, columns=cols, show='headings')
    for col in cols:
        if col == 'TOKEN':
            box.heading(col, text=col, command =token)
        box.grid(row=1, column=0, columnspan=2,sticky='nsew')