Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tkinter ttk treeview colored rows

I am trying to set colors to rows in a tkinter treeview object, using tags and tag_configure.

There has been an earlier discussion on coloring rows which is rather old and seems to work no longer for Python3:

ttk treeview: alternate row colors

I have added a brief example. For me, all rows stay white, independent of whether I execute tag_configure prior or after the insert command.

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
w = tk.Label(root, text="Hello, world!")
w.pack()

lb= ttk.Treeview(root, columns=['number', 'text'], show="headings", height =20)
lb.tag_configure('gr', background='green')
lb.column("number", anchor="center", width=10)    
lb.insert('',tk.END, values = ["1","testtext1"], tags=('gr',))
lb.insert('',tk.END, values = ["2","testtext2"])

lb.pack()

root.mainloop()

What has changed or what am I missing?

EDIT: Seems that this is a new known bug with a workaround, but I don't get this working: https://core.tcl-lang.org/tk/tktview?name=509cafafae

EDIT2: I am now using tk Version 8.6.10 (Build hfa6e2cd_0, Channel conda-forge) and python 3.7.3. Can anyone reproduce this error with this version of python and tk?

like image 204
tfv Avatar asked Apr 22 '20 19:04

tfv


2 Answers

You no longer need to use fixed_map the bug was fixed in tkinter version 8.6. The following code works fine for me using tkinter 8.6 and python 3.8.2 running in Linux.

import tkinter as tk
import tkinter.ttk as ttk

def fixed_map(option):
    return [elm for elm in style.map("Treeview", query_opt=option) if elm[:2] != ("!disabled", "!selected")]

root = tk.Tk()
style = ttk.Style()
style.map("Treeview", foreground=fixed_map("foreground"), background=fixed_map("background"))

w = tk.Label(root, text="Hello, world!")
w.pack()

lb= ttk.Treeview(root, columns=['number', 'text'], show="headings", height =20)
lb.tag_configure('odd', background='green')
lb.tag_configure('even', background='lightgreen')

lb.column("number", anchor="center", width=10)
lb.insert('', tk.END, values = ["1","testtext1"], tags=('odd',))
lb.insert('', tk.END, values = ["2","testtext2"], tags=('even',))
lb.insert('', tk.END, values = ["3","testtext3"], tags=('odd',))
lb.insert('', tk.END, values = ["4","testtext4"], tags=('even',))

lb.pack()

root.mainloop()
like image 71
Daniel Huckson Avatar answered Sep 20 '22 17:09

Daniel Huckson


That answer of Chuck666 did the trick: https://stackoverflow.com/a/60949800/4352930

This code works

import tkinter as tk
import tkinter.ttk as ttk

def fixed_map(option):
    # Returns the style map for 'option' with any styles starting with
    # ("!disabled", "!selected", ...) filtered out

    # style.map() returns an empty list for missing options, so this should
    # be future-safe
    return [elm for elm in style.map("Treeview", query_opt=option)
            if elm[:2] != ("!disabled", "!selected")]



root = tk.Tk()

style = ttk.Style()
style.map("Treeview", 
          foreground=fixed_map("foreground"),
          background=fixed_map("background"))

w = tk.Label(root, text="Hello, world!")
w.pack()

lb= ttk.Treeview(root, columns=['number', 'text'], show="headings", height =20)
lb.tag_configure('gr', background='green')
lb.column("number", anchor="center", width=10)    
lb.insert('',tk.END, values = ["1","testtext1"], tags=('gr',))
lb.insert('',tk.END, values = ["2","testtext2"])

lb.pack()

root.mainloop()

I hope that Chuck666 copies his answer here since I think he has earned the bonus if he shows up.

like image 22
tfv Avatar answered Sep 19 '22 17:09

tfv