Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

python 3.x - Tkinter Treeview heading styling

I want to change the background colour of the treeview headings. I have identified the element option of the Treeview.Heading layout responsible for this: Treeheading.cell. The problem is that this setting does not work on the 'vista' theme (Due to drawing issues I assume).

working code (theme looks terrible though):

from tkinter import *
from tkinter import ttk

p=Tk()

separator = PanedWindow(p,bd=0,bg="#202322",sashwidth=2)

separator.pack(fill=BOTH, expand=1)

_frame = Frame(p,bg="#383838")

t=ttk.Treeview(_frame)

t["columns"]=("first","second")
t.column("first",anchor="center" )
t.column("second")
t.heading("first",text="first column")
t.heading("second",text="second column")
t.insert("",0,"dir1",text="directory 1")
t.insert("dir1","end","dir 1",text="file 1 1",values=("file 1 A","file 1 B"))
id=t.insert("","end","dir2",text="directory 2")
t.insert("dir2","end",text="dir 2",values=("file 2 A","file 2 B"))
t.insert(id,"end",text="dir 3",values=("val 1 ","val 2"))
t.insert("",0,text="first line",values=("first line 1","first line 2"))
t.tag_configure("ttk",foreground="black")

ysb = ttk.Scrollbar(orient=VERTICAL, command= t.yview)
xsb = ttk.Scrollbar(orient=HORIZONTAL, command= t.xview)
t['yscroll'] = ysb.set
t['xscroll'] = xsb.set

print(ttk.Style().theme_names())

ttk.Style().theme_use('default')


ttk.Style().configure("Treeview", background="#383838",foreground="white")
ttk.Style().configure("Treeview.Heading",background = "blue",foreground="Black")
p.configure(background='black')

t.grid(in_=_frame, row=0, column=0, sticky=NSEW)
ysb.grid(in_=_frame, row=0, column=1, sticky=NS)
xsb.grid(in_=_frame, row=1, column=0, sticky=EW)
_frame.rowconfigure(0, weight=1)
_frame.columnconfigure(0, weight=1)

separator.add(_frame)

w = Text(separator)
separator.add(w)

p.mainloop()

my attempt using 'vista' theme:

ttk.Style().element_create("Treeheading.cell","from","default")

ttk.Style().configure("Treeview", background="#383838",foreground="white")
ttk.Style().configure("Treeview.Heading",background = "Blue")

element_create has worked in other instances of this problem but with different widgets. Thank you, any help would be appreciated.

working in python 3. Also the code is not mine, I found it and used it to test.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are on the right track but need to change the border element rather than the cell element. As you are working on Windows, the treeview cells are being displayed using a system provided theme element from the Visual Styles API. In this case it is a HP_HEADERITEM part from the HEADER class. As this is drawn by the system theme engine you don't get to customise it from Tk aside from selecting alternate looks according to the state.

If you must customise the look of the header then you have to replace the theme part with one that Tk can customise and the default theme is a good choice. I would also recommend that you define this as a custom style so that you can re-style specific widgets and not necessarily all of them.

style = ttk.Style()
style.element_create("Custom.Treeheading.border", "from", "default")
style.layout("Custom.Treeview.Heading", [
    ("Custom.Treeheading.cell", {'sticky': 'nswe'}),
    ("Custom.Treeheading.border", {'sticky':'nswe', 'children': [
        ("Custom.Treeheading.padding", {'sticky':'nswe', 'children': [
            ("Custom.Treeheading.image", {'side':'right', 'sticky':''}),
            ("Custom.Treeheading.text", {'sticky':'we'})
        ]})
    ]}),
])
style.configure("Custom.Treeview.Heading",
    background="blue", foreground="white", relief="flat")
style.map("Custom.Treeview.Heading",
    relief=[('active','groove'),('pressed','sunken')])

What we are doing is defining a new widget style using the same layout as for the standard treeview style and replacing the border element. While we have not defined the other custom elements, these are looked up hierarchically so in the absence of a Custom.Treeheading.text it will use a Treeheading.text. To use this, we set the style of the treeview widget:

t=ttk.Treeview(_frame, style="Custom.Treeview")

Ends up looking like this on Windows 10:

screenshot of custom treeview


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...