The Text widget allow rich text. However, it's quite
difficult to use. You need to set each attribute
(font, style, highlight, color) of the widget
before adding more text with differert style.
So, I make a function that make it a bit easier.
The font tag (<font></font>) is used (borrowed from HTML).
Attributes allowed are
- color ( #RRGGBB or 0xRRGGBB or color name)
- face ( both font and size eg. albi17b )
- style ( bold, italic, underline or strikethrough )
(styles can be combined using comma)
- highlight ( standard, rounded, shadow)
- hcolor ( highlight color )
from appuifw import *
def process_color(color):
color_name = {
'red': 0xff0000, 'green': 0x008000, 'blue':0x0000ff,
'black': 0, 'white':0xffffff, 'yellow': 0xffff00
}
if color.startswith('#'):
return int(color[1:], 16)
if color.startswith('0x'):
return int(color, 16)
return color_name[color]
def set_ml(t, s):
stack = []
t.clear()
t.font = 'normal'
i = 0
while i < len(s):
if s.startswith('<', i):
j = s.find('>', i) + 1
if s[i:i+7] == '</font>' or s[i:i+3] == '</>':
t.color, t.font, t.style, t.highlight_color = stack.pop()
else:
stack.append([t.color, t.font, t.style, t.highlight_color])
to_style = 0
for attr_val in s[i:j-1].split(' '):
if '=' in attr_val:
attr, val = attr_val.split('=')
if attr == 'color':
t.color = process_color(val)
elif attr == 'face':
t.font = unicode(val)
elif attr == 'hcolor':
t.highlight_color = process_color(val)
elif attr == 'style':
to_style |= eval('|'.join(['STYLE_' + st.upper() for st in val.split(',')]))
elif attr == 'highlight':
to_style |= eval("HIGHLIGHT_" + val.upper())
if to_style:
t.style = to_style
else:
j = s.find('<', i)
if j == -1: j = len(s)
text = u'' + s[i:j].replace('<', '<')
t.add(text)
i = j
Now you can use it easily
>>> t = app.body
>>> set_ml(t, '<font color=red>Hello</font> <font style=bold>World</font>.')
>>>
Notice:
- Quotation marks are not used to specify attribute values.
- A </> shorthand can be used for </font>
- <font> can be nested.