Many Tkinter widgets let you specify custom font specifications either at the time of widget creation or later using the configure()
option. For most cases, default fonts provide a standard look and feel. However, should you want to change font specifications, Tkinter lets you do so. There is one caveat though.
When you specify your own font, you need to make sure it looks good on all platforms where the program is intended to be deployed. This is because a font might look good and match well on a particular platform, but may look awful on another. Unless you know what you are doing, it is always advisable to stick to Tkinter's default fonts.
Most platforms have their own set of standard fonts that are used by the platform's native widgets. So, rather than trying to reinvent the wheel on what looks good on a given platform or what would be available for a given platform, Tkinter assigns these standard platform-specific fonts into its widget, thus providing a native look and feel on every platform.
Accordingly, you can use them in your programs in the following way:
Label(text="Sale Up to 50% Off !", font="TkHeadingFont 20") Label(text="**Conditions Apply", font="TkSmallCaptionFont 8")
Using these kinds of fonts mark up, you can be assured that your font will look native across all platforms.
In addition to the above method on handling fonts, Tkinter provides a separate Font
class implementation. The source code of this class is located at the following link: <Python27_installtion_dir>Liblib-tk kfont.py
.
To use this module, you need to import tkFont
into your namespace.(refer to 8.08 tkfont demo.py
):
from Tkinter import Tk, Label, Pack import tkFont root=Tk() label = Label(root, text="Humpty Dumpty was pushed") label.pack() currentfont = tkFont.Font(font=label['font']) print'Actual :' + str(currentfont.actual()) print'Family :' + currentfont.cget("family") print'Weight :' + currentfont.cget("weight") print'Text width of Dumpty : %d' %currentfont.measure("Dumpty") print'Metrics:' + str(currentfont.metrics()) currentfont.config(size=14) label.config (font=currentfont) print'New Actual :' + str(currentfont.actual()) root.mainloop()
The console output of this program is as follows:
Actual :{'family': 'Segoe UI', 'weight': 'normal', 'slant': 'roman', 'overstrike': 0, 'underline': 0, 'size': 9} Family : Segoe UI Weight : normal Text width of Dumpty : 43 Metrics:{'fixed': 0, 'ascent': 12, 'descent': 3, 'linespace': 15}
As you can see, the tkfont
module provides a much better fine-grained control over various aspects of fonts, which are otherwise inaccessible.
Now that we have seen the basic features available in the tkfont
module, let's use it to implement a font selector. The font selector would look like the one shown here:
The code for the font selector is as follows (refer to 8.09 font selector.py
):
from Tkinter import * import ttk import tkFont class FontSelectorDemo(): def __init__(self): self.currentfont = tkFont.Font(font=('Times New Roman',12)) self.family = StringVar(value='Times New Roman') self.fontsize = StringVar(value='12') self.fontweight =StringVar(value=tkFont.NORMAL) self.slant = StringVar(value=tkFont.ROMAN) self.underlinevalue = BooleanVar(value=False) self.overstrikevalue= BooleanVar(value=False) self.gui_creator()
The description of the preceding code is as follows:
Tkinter
(for all widgets), ttk
(for the Combobox widget), and tkfont
for handling font-related aspects of the programFontSelectorDemo
and use its __init_
method to initialize al attributes that we intend to track in our program.__init__
method calls another method named gui_creator()
, which is be responsible for creating all the GUI elements of the programThe code represented here is a highly abridged version of the actual code (refer to 8.09 font selector.py
). Here, we removed all the code that creates basic widgets, such as Label and Checkbuttons, in order to show only the font-related code:
def gui_creator(self): # create the top labels – code removed fontList = ttk.Combobox(textvariable=self.family) fontList.bind('<<ComboboxSelected>>', self.on_value_change) allfonts = list(tkFont.families()) allfonts.sort() fontList['values'] = allfonts # Font Sizes sizeList = ttk.Combobox(textvariable=self.fontsize) sizeList.bind('<<ComboboxSelected>>', self.on_value_change) allfontsizes = range(6,70) sizeList['values'] = allfontsizes # add four checkbuttons to provide choice for font style # all checkbuttons command attached to self.on_value_change #create text widget sampletext ='The quick brown fox jumps over the lazy dog' self.text.insert(INSERT,'%s %s'% (sampletext,sampletext.upper()),'fontspecs') self.text.config(state=DISABLED)
The description of the preceding code is as follows:
tkfont.families()
to fetch the list of all the fonts installed on a computer. This is converted into a list format and sorted before it is inserted into the fontList
Combobox widget.6
to 70
in the Font Size combobox.fontspec
.on_value_change
. This method will be responsible for updating the display of the sample text at the time of changes in the values of any of the widgets.def on_value_change(self, event=None):
try:
self.currentfont.config(family=self.family.get(), size=self.fontsize.get(), weight=self.fontweight.get(), slant=self.slant.get(), underline=self.underlinevalue.get(), overstrike=self.overstrikevalue.get())
self.text.tag_config('fontspecs', font=self.currentfont)
except ValueError:
pass ### invalid entry - ignored for now. You can use a tkMessageBox dialog to show an error
The description of the preceding code is as follows:
currentfont
attribute with the updated font valuesfontspec
with the values of the current font13.58.50.156