Reputation: 1247
I'm trying to change the font in a tkinter treeview but can't figure out how to do it. I can change the treeview column header font but not the font in the rows. The demo below uses a spinbox to change the font size. I have tried using "TkTextFont" but it didn't work, it changes the font size in the spinbox but not the treeview..
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
class MySpinbox(ttk.Spinbox):
def __init__(self, master=None, delay=250, **kwargs):
ttk.Spinbox.__init__(self, master, **kwargs)
self.delay = delay # repeatdelay in ms
self.bind('<<Increment>>', self._on_increment)
self.bind('<<Decrement>>', self._on_decrement)
self._increment_lock = False
self._decrement_lock = False
def _unlock_increment(self):
self._increment_lock = False
def _on_increment(self, event):
if self._increment_lock:
return "break" # stop the increment
else:
# generate a virtual event corresponding to when the spinbox
# is actually incremented
self.event_generate('<<ActualIncrement>>')
self._increment_lock = True
self.after(self.delay, self._unlock_increment)
def _unlock_decrement(self):
self._decrement_lock = False
def _on_decrement(self, event):
if self._decrement_lock:
return "break" # stop the increment
else:
# generate a virtual event corresponding to when the spinbox
# is actually decremented
self.event_generate('<<ActualDecrement>>')
self._decrement_lock = True
self.after(self.delay, self._unlock_decrement)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.title('Treeview Demo')
self.geometry('420x200+20+20')
style = ttk.Style()
var = tk.StringVar()
var.set(9)
tv = self.tv = ttk.Treeview(self)
tv.grid(row=0, column=0, sticky='NSEW')
def size():
font = tkfont.nametofont('TkHeadingFont')
font.config(size=var.get())
style.configure('Treeview.Heading', font=font)
font = tkfont.nametofont('TkTextFont')
font.config(size=var.get())
spn = MySpinbox(self, textvariable=var, values=list(range(0, 1000)), command=size)
spn.grid(row=0, column=1, pady=5, padx=20)
tv.heading('#0', text='Name')
tv.insert('', '0', 'item1', text='Item 1')
tv.insert('', '1', 'item2', text='Item 2')
tv.insert('', '2', 'item3', text='Item 3')
tv.insert('item1', '0', 'python1', text='Python 1')
tv.insert('item1', '1', 'python2', text='Python 2')
tv.insert('python1', '0', 'sub1', text='Sub item 1')
tv.insert('python1', '1', 'sub2', text='Sub item 2')
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
Upvotes: 2
Views: 6155
Reputation: 1247
I just figured out how to set the font in a treeview and I'm posting my solution here, case someone else has the same problem. It seems that treeview doesn't respond to named fonts, you have to configure tags using
treeview.tag_configure()
and set the tags argument when inserting items in the tree. I think this is the only way to do it.
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
class MySpinbox(ttk.Spinbox):
def __init__(self, master=None, delay=100, **kwargs):
ttk.Spinbox.__init__(self, master, **kwargs)
self.delay = delay # repeatdelay in ms
self.bind('<<Increment>>', self._on_increment)
self.bind('<<Decrement>>', self._on_decrement)
self._increment_lock = False
self._decrement_lock = False
def _unlock_increment(self):
self._increment_lock = False
def _on_increment(self, event):
if self._increment_lock:
return "break" # stop the increment
else:
# generate a virtual event corresponding to when the spinbox
# is actually incremented
self.event_generate('<<ActualIncrement>>')
self._increment_lock = True
self.after(self.delay, self._unlock_increment)
def _unlock_decrement(self):
self._decrement_lock = False
def _on_decrement(self, event):
if self._decrement_lock:
return "break" # stop the increment
else:
# generate a virtual event corresponding to when the spinbox
# is actually decremented
self.event_generate('<<ActualDecrement>>')
self._decrement_lock = True
self.after(self.delay, self._unlock_decrement)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.title('Treeview Demo')
self.geometry('420x200+20+20')
style = ttk.Style()
var = tk.StringVar()
var.set(9)
tv = self.tv = ttk.Treeview(self)
tv.grid(row=0, column=0, sticky='NSEW')
font = tkfont.nametofont('TkTextFont')
tv.tag_configure('TkTextFont', font=tkfont.nametofont('TkTextFont'))
style.configure('Treeview', rowheight=font.metrics('linespace'))
def size():
_font = tkfont.nametofont('TkHeadingFont')
_font.config(size=var.get())
style.configure('Treeview.Heading', font=_font)
_font = tkfont.nametofont('TkTextFont')
_font.configure(size=var.get())
style.configure('Treeview', rowheight=_font.metrics('linespace'))
spn = MySpinbox(self, textvariable=var, values=list(range(0, 1000)), command=size)
spn.grid(row=0, column=1, pady=5, padx=20)
tv.heading('#0', text='Name')
tv.insert('', '0', 'item1', text='Item 1', tags='TkTextFont')
tv.insert('', '1', 'item2', text='Item 2', tags='TkTextFont')
tv.insert('', '2', 'item3', text='Item 3', tags='TkTextFont')
tv.insert('item1', '0', 'python1', text='Python 1', tags='TkTextFont')
tv.insert('item1', '1', 'python2', text='Python 2', tags='TkTextFont')
tv.insert('python1', '0', 'sub1', text='Sub item 1', tags='TkTextFont')
tv.insert('python1', '1', 'sub2', text='Sub item 2', tags='TkTextFont')
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
Upvotes: 2
Reputation: 528
It probably does respond to named fonts, but you have to guess the right name.
tk.splitlist(tk.call("font", "names"))
will get you a list of the names it uses. Then you can try changing the size of each one to find out which one it uses.
Upvotes: 0