2

i have created a Treeview and changed the selected color using this code:

style = self.style = ttk.Style(win)
        style.theme_create("my", "vista",
                           settings={
                               'Treeview': {
                                   'map': {
                                       'background': [('selected', '#ffdddd'), ("!selected", "white")],
                                       'foreground': [('selected', 'black')],
                                       "font": [("", ("", 13))]
                                   }  # end 'map'
                               },  # end 'Treeview'
                               'TNotebook.Tab': {
                                   'map': {
                                       'font': [("", ("", 14))]
                                   }  # end 'map'
                               },  # end 'TNotebook.Tab'
                               'TNotebook': {
                                   'map': {
                                       'background': [("", "#eee")]
                                   }  # end 'map'
                               }  # end 'TNotebook
                           }  # end settings
                           )
        style.theme_use("my")

The code works fine, but when i try to change background color of specific item's (rows) using tag_configure method nothing changes, i found that this is a tkinter bug, the solution is this code: (it is working without using the above theme)

def fixed_map(option):
    # Fix for setting text colour for Tkinter 8.6.9
    # From: https://core.tcl.tk/tk/info/509cafafae
    #
    # 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')]

style.map('Treeview', foreground=fixed_map('foreground'), background=fixed_map('background'))

so the problem is while i want to specify the selected background, i can't change background color of items and tag_configure is not affecting anything. am i missing something or is there any other way to do this?

  • 1
    Do you really need to create a new style, can't you just modify the existing one using `style.map()` to change the background color of the selected item? When I do that, `tag_configure()`works as expected. – j_4321 Apr 09 '20 at 08:02
  • @j_4321thanks for your answer, actually i found that the theme is replacing the background color of tag_configure(), so i replaced the theme with style.map(), works just as i wanted to, thanks by the way. – Esmail Mahjoor Apr 09 '20 at 08:07

1 Answers1

2

On windows 10, Python 3.9.0, I've the same problem. Altering font with tag_configure works fine, but not background nor foreground. I'm new to tkinter, spend many hours on this problem and found the above solution after I had a workaround - with a copy of the actual used theme everything seams to work.

My workaround:

    style = ttk.Style(self)
    aktualTheme = style.theme_use()
    style.theme_create("dummy", parent=aktualTheme)
    style.theme_use("dummy")

The program to isolate the problem. With zebra = 0 (line 10), I don't get the expected result

import tkinter as tk
from tkinter import ttk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Treeview Zebra')
        self.geometry('620x250')

        zebra = 1
        if zebra:
            style = ttk.Style(self)
            aktualTheme = style.theme_use()
            style.theme_create("dummy", parent=aktualTheme)
            style.theme_use("dummy")

        self.tree = ttk.Treeview(self, columns=('F1', 'F2'), show='headings')
        self.tree.heading('F1', text='Field 1')
        self.tree.heading('F2', text='Field 2')
        self.tree.pack()

        # tags to tree
        self.tree.tag_configure('odd', background='#E6B3FF')
        self.tree.tag_configure('even', background='#DD99FF', foreground='white')
        self.tree.tag_configure('A10', background='#E6B3FF', font='Arial 10')
        self.tree.tag_configure('S', background='#DFDFDF', font=('Calibri', 9, 'bold'))

        # adding generated sample data to the treeview
        for n in range(1, 7):
            if n % 2 :
                self.tree.insert('', tk.END, values=(f'first {n}', f'last {n}', f'email{n}@example.com'), tags = ('S'))
            else:
                self.tree.insert('', tk.END, values=(f'first {n}', f'last {n}', f'email{n}@example.com'), tags = ('even', 'A10'))

if __name__ == "__main__":
    app = App()
    app.mainloop()

zebra = 0, only altering font

zebra = 1, + altering colours

Lutz
  • 31
  • 5