6

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?

tfv
  • 6,016
  • 4
  • 36
  • 67
  • 1
    I've executed your code - it works. What is your Tkinter version? (To check it type `from tkinter import TkVersion; TkVersion` in interactive mode, though never use ; in your real code) – Demian Wolf Apr 22 '20 at 21:01
  • 1
    Tkinter version is 8.6, python version is 3.7.3 – tfv Apr 22 '20 at 21:03
  • `no longer for Python3` -- this is an absolutely wrong sentence because Tk version is independent of Python version (though there is the default-installed Tk version, of course) – Demian Wolf Apr 22 '20 at 21:03
  • @Bryan Oakley Which version of python do you use? It does not work in my python 3.7.3. version, and I have some other similar code which works in my 2.7, so I was assuming that this is related to the python version. Maybe I am wrong. – tfv Apr 22 '20 at 21:07
  • 1
    By the way, have you tried to set the style of the Treeview? I mean, `lb = ttk.Treeview(root, ...., style="Treeview") – Demian Wolf Apr 22 '20 at 21:07
  • 1
    @DemianWolf I have tried to implement the code of that workaround, but did not get this style command working properly. It does not work if I just add style=Treeview" to the ttk.Treeview command. – tfv Apr 22 '20 at 21:08

2 Answers2

3

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()
Daniel Huckson
  • 1,157
  • 1
  • 13
  • 35
  • 1
    In windows, tkinter 8.6.8. and python 3.8.2 do not work. Which subversion of tkinter 3.8. are you using (you'll see it with `conda list tk`) – tfv Apr 27 '20 at 04:52
  • 1
    I'm not using Anaconda. The code above works in Linux, I tried it on Windows 10 and you will need to still use the fixed_map function to make it work. I edited the code to show this. – Daniel Huckson Apr 27 '20 at 13:52
  • 1
    You can also have a look at this post maybe it will help, look at the working example at the end of the post, it's been tested in Windows and Linux. https://stackoverflow.com/questions/61350804/tkinter-treeview-how-to-correctly-select-multiple-items-with-the-mouse – Daniel Huckson Apr 27 '20 at 14:48
  • I have decided to only auto-award this answer since it is only a copy of my answer, so I am not sure that it deserves the full bounty. Unfortunately Chuck666 did not show up to collect his bounty. Thanks for your help! – tfv May 03 '20 at 08:32
1

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.

tfv
  • 6,016
  • 4
  • 36
  • 67