blob: 229f2513e7177f8769ff750c0d822bb15b767664 [file] [log] [blame]
# Tkinter font wrapper
# written by Fredrik Lundh, February 1998
# FIXME: should add 'displayof' option where relevant (actual, families,
# measure, and metrics)
__version__ = "0.9"
import Tkinter
# weight/slant
NORMAL = "normal"
ROMAN = "roman"
BOLD = "bold"
ITALIC = "italic"
def nametofont(name):
"""Given the name of a tk named font, returns a Font representation.
return Font(name=name, exists=True)
class Font:
"""Represents a named font.
Constructor options are:
font -- font specifier (name, system font, or (family, size, style)-tuple)
name -- name to use for this font configuration (defaults to a unique name)
exists -- does a named font by this name already exist?
Creates a new named font if False, points to the existing font if True.
Raises _Tkinter.TclError if the assertion is false.
the following are ignored if font is specified:
family -- font 'family', e.g. Courier, Times, Helvetica
size -- font size in points
weight -- font thickness: NORMAL, BOLD
slant -- font slant: ROMAN, ITALIC
underline -- font underlining: false (0), true (1)
overstrike -- font strikeout: false (0), true (1)
def _set(self, kw):
options = []
for k, v in kw.items():
return tuple(options)
def _get(self, args):
options = []
for k in args:
return tuple(options)
def _mkdict(self, args):
options = {}
for i in range(0, len(args), 2):
options[args[i][1:]] = args[i+1]
return options
def __init__(self, root=None, font=None, name=None, exists=False, **options):
if not root:
root = Tkinter._default_root
if font:
# get actual settings corresponding to the given font
font ="font", "actual", font))
font = self._set(options)
if not name:
name = "font" + str(id(self)) = name
if exists:
self.delete_font = False
# confirm font exists
if not in"font", "names"):
raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (,)
# if font config info supplied, apply it
if font:"font", "configure",, *font)
# create new font (raises TclError if the font exists)"font", "create",, *font)
self.delete_font = True
# backlinks!
self._root = root
self._split =
self._call =
def __str__(self):
def __eq__(self, other):
return == and isinstance(other, Font)
def __getitem__(self, key):
return self.cget(key)
def __setitem__(self, key, value):
self.configure(**{key: value})
def __del__(self):
if self.delete_font:
self._call("font", "delete",
except (KeyboardInterrupt, SystemExit):
except Exception:
def copy(self):
"Return a distinct copy of the current font"
return Font(self._root, **self.actual())
def actual(self, option=None):
"Return actual font attributes"
if option:
return self._call("font", "actual",, "-"+option)
return self._mkdict(
self._split(self._call("font", "actual",
def cget(self, option):
"Get font attribute"
return self._call("font", "config",, "-"+option)
def config(self, **options):
"Modify font attributes"
if options:
self._call("font", "config",,
return self._mkdict(
self._split(self._call("font", "config",
configure = config
def measure(self, text):
"Return text width"
return int(self._call("font", "measure",, text))
def metrics(self, *options):
"""Return font metrics.
For best performance, create a dummy widget
using this font before calling this method."""
if options:
return int(
self._call("font", "metrics",, self._get(options))
res = self._split(self._call("font", "metrics",
options = {}
for i in range(0, len(res), 2):
options[res[i][1:]] = int(res[i+1])
return options
def families(root=None):
"Get font families (as a tuple)"
if not root:
root = Tkinter._default_root
return"font", "families"))
def names(root=None):
"Get names of defined fonts (as a tuple)"
if not root:
root = Tkinter._default_root
return"font", "names"))
# --------------------------------------------------------------------
# test stuff
if __name__ == "__main__":
root = Tkinter.Tk()
# create a font
f = Font(family="times", size=30, weight=NORMAL)
print f.actual()
print f.actual("family")
print f.actual("weight")
print f.config()
print f.cget("family")
print f.cget("weight")
print names()
print f.measure("hello"), f.metrics("linespace")
print f.metrics()
f = Font(font=("Courier", 20, "bold"))
print f.measure("hello"), f.metrics("linespace")
w = Tkinter.Label(root, text="Hello, world", font=f)
w = Tkinter.Button(root, text="Quit!", command=root.destroy)
fb = Font(font=w["font"]).copy()