0001 # 0002 # Tkinter 0003 # $Id: tkFont.py,v 1.9 2004/08/20 06:19:23 loewis Exp $ 0004 # 0005 # font wrapper 0006 # 0007 # written by Fredrik Lundh <fredrik@pythonware.com>, February 1998 0008 # 0009 # FIXME: should add 'displayof' option where relevant (actual, families, 0010 # measure, and metrics) 0011 # 0012 # Copyright (c) Secret Labs AB 1998. 0013 # 0014 # info@pythonware.com 0015 # http://www.pythonware.com 0016 # 0017 0018 __version__ = "0.9" 0019 0020 import Tkinter 0021 0022 # weight/slant 0023 NORMAL = "normal" 0024 ROMAN = "roman" 0025 BOLD = "bold" 0026 ITALIC = "italic" 0027 0028 def nametofont(name): 0029 """Given the name of a tk named font, returns a Font representation. 0030 """ 0031 return Font(name=name, exists=True) 0032 0033 class Font: 0034 0035 """Represents a named font. 0036 0037 Constructor options are: 0038 0039 font -- font specifier (name, system font, or (family, size, style)-tuple) 0040 name -- name to use for this font configuration (defaults to a unique name) 0041 exists -- does a named font by this name already exist? 0042 Creates a new named font if False, points to the existing font if True. 0043 Raises _tkinter.TclError if the assertion is false. 0044 0045 the following are ignored if font is specified: 0046 0047 family -- font 'family', e.g. Courier, Times, Helvetica 0048 size -- font size in points 0049 weight -- font thickness: NORMAL, BOLD 0050 slant -- font slant: ROMAN, ITALIC 0051 underline -- font underlining: false (0), true (1) 0052 overstrike -- font strikeout: false (0), true (1) 0053 0054 """ 0055 0056 def _set(self, kw): 0057 options = [] 0058 for k, v in kw.items(): 0059 options.append("-"+k) 0060 options.append(str(v)) 0061 return tuple(options) 0062 0063 def _get(self, args): 0064 options = [] 0065 for k in args: 0066 options.append("-"+k) 0067 return tuple(options) 0068 0069 def _mkdict(self, args): 0070 options = {} 0071 for i in range(0, len(args), 2): 0072 options[args[i][1:]] = args[i+1] 0073 return options 0074 0075 def __init__(self, root=None, font=None, name=None, exists=False, **options): 0076 if not root: 0077 root = Tkinter._default_root 0078 if font: 0079 # get actual settings corresponding to the given font 0080 font = root.tk.splitlist(root.tk.call("font", "actual", font)) 0081 else: 0082 font = self._set(options) 0083 if not name: 0084 name = "font" + str(id(self)) 0085 self.name = name 0086 0087 if exists: 0088 self.delete_font = False 0089 # confirm font exists 0090 if self.name not in root.tk.call("font", "names"): 0091 raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,) 0092 # if font config info supplied, apply it 0093 if font: 0094 root.tk.call("font", "configure", self.name, *font) 0095 else: 0096 # create new font (raises TclError if the font exists) 0097 root.tk.call("font", "create", self.name, *font) 0098 self.delete_font = True 0099 # backlinks! 0100 self._root = root 0101 self._split = root.tk.splitlist 0102 self._call = root.tk.call 0103 0104 def __str__(self): 0105 return self.name 0106 0107 def __eq__(self, other): 0108 return self.name == other.name and isinstance(other, Font) 0109 0110 def __getitem__(self, key): 0111 return self.cget(key) 0112 0113 def __setitem__(self, key, value): 0114 self.configure(**{key: value}) 0115 0116 def __del__(self): 0117 try: 0118 if self.delete_font: 0119 self._call("font", "delete", self.name) 0120 except (AttributeError, Tkinter.TclError): 0121 pass 0122 0123 def copy(self): 0124 "Return a distinct copy of the current font" 0125 return Font(self._root, **self.actual()) 0126 0127 def actual(self, option=None): 0128 "Return actual font attributes" 0129 if option: 0130 return self._call("font", "actual", self.name, "-"+option) 0131 else: 0132 return self._mkdict( 0133 self._split(self._call("font", "actual", self.name)) 0134 ) 0135 0136 def cget(self, option): 0137 "Get font attribute" 0138 return self._call("font", "config", self.name, "-"+option) 0139 0140 def config(self, **options): 0141 "Modify font attributes" 0142 if options: 0143 self._call("font", "config", self.name, 0144 *self._set(options)) 0145 else: 0146 return self._mkdict( 0147 self._split(self._call("font", "config", self.name)) 0148 ) 0149 0150 configure = config 0151 0152 def measure(self, text): 0153 "Return text width" 0154 return int(self._call("font", "measure", self.name, text)) 0155 0156 def metrics(self, *options): 0157 """Return font metrics. 0158 0159 For best performance, create a dummy widget 0160 using this font before calling this method.""" 0161 0162 if options: 0163 return int( 0164 self._call("font", "metrics", self.name, self._get(options)) 0165 ) 0166 else: 0167 res = self._split(self._call("font", "metrics", self.name)) 0168 options = {} 0169 for i in range(0, len(res), 2): 0170 options[res[i][1:]] = int(res[i+1]) 0171 return options 0172 0173 def families(root=None): 0174 "Get font families (as a tuple)" 0175 if not root: 0176 root = Tkinter._default_root 0177 return root.tk.splitlist(root.tk.call("font", "families")) 0178 0179 def names(root=None): 0180 "Get names of defined fonts (as a tuple)" 0181 if not root: 0182 root = Tkinter._default_root 0183 return root.tk.splitlist(root.tk.call("font", "names")) 0184 0185 # -------------------------------------------------------------------- 0186 # test stuff 0187 0188 if __name__ == "__main__": 0189 0190 root = Tkinter.Tk() 0191 0192 # create a font 0193 f = Font(family="times", size=30, weight=NORMAL) 0194 0195 print f.actual() 0196 print f.actual("family") 0197 print f.actual("weight") 0198 0199 print f.config() 0200 print f.cget("family") 0201 print f.cget("weight") 0202 0203 print names() 0204 0205 print f.measure("hello"), f.metrics("linespace") 0206 0207 print f.metrics() 0208 0209 f = Font(font=("Courier", 20, "bold")) 0210 print f.measure("hello"), f.metrics("linespace") 0211 0212 w = Tkinter.Label(root, text="Hello, world", font=f) 0213 w.pack() 0214 0215 w = Tkinter.Button(root, text="Quit!", command=root.destroy) 0216 w.pack() 0217 0218 fb = Font(font=w["font"]).copy() 0219 fb.config(weight=BOLD) 0220 0221 w.config(font=fb) 0222 0223 Tkinter.mainloop() 0224
Generated by PyXR 0.9.4