Recipe11.5.Entering Accented Characters in Tkinter Widgets


Recipe 11.5. Entering Accented Characters in Tkinter Widgets

Credit: Artur de Sousa Rocha

Problem

You want your application to allow the user to easily enter accented characters into Tkinter widgets even from a U.S.-layout keyboard.

Solution

Internationalized applications should enable the user to easily enter letters with accents and diacritics (e.g., umlauts, and tildes) even from a U.S.-layout keyboard. A usefully uniform convention is the following: hitting Ctrl-accent, for any kind of accent or diacritic, acts as a dead key, ensuring that the next letter hit will be decorated by that accent or diacritic. For example, Ctrl-apostrophe, followed by a, enters an a with an acute accent (the character á). The following classes provide the keyboard and widget bindings that allow this internationalized input functionality:

from Tkinter import * from ScrolledText import ScrolledText from unicodedata import lookup import os class Diacritical(object):     """ Mixin class that adds keyboard bindings for accented characters, plus         other common functionality (e.g.: Control-A == 'select all' on Windows).     """     if os.name == "nt":         stroke = '/'     else:         stroke = 'minus'     accents = (('acute', "'"), ('grave', '`'), ('circumflex', '^'),                ('tilde', '='), ('diaeresis', '"'), ('cedilla', ','),                ('stroke', stroke))     def _ _init_ _(self):         # Fix some non-Windows-like Tk bindings, if we're on Windows         if os.name == 'nt':             self.bind("<Control-Key-a>", self.select_all)             self.bind("<Control-Key-/>", lambda event: "break")         # Diacritical bindings         for a, k in self.accents:             self.bind("<Control-Key-%s><Key>" % k,                         lambda event, a=a: self.insert_accented(event.char, a))     def insert_accented(self, c, accent):         if c.isalpha( ):             if c.isupper( ):                 cap = 'capital'             else:                 cap = 'small'             try:                 c = lookup("latin %s letter %c with %s" % (cap, c, accent))                 self.insert(INSERT, c)                 return "break"             except KeyError, e:                 pass class DiacriticalEntry(Entry, Diacritical):     """ Tkinter Entry widget with some extra key bindings for         entering typical Unicode characters - with umlauts, accents, etc. """     def _ _init_ _(self, master=None, **kwargs):         Entry._ _init_ _(self, master=None, **kwargs)         Diacritical._ _init_ _(self)     def select_all(self, event=None):         self.selection_range(0, END)         return "break" class DiacriticalText(ScrolledText, Diacritical):     """ Tkinter ScrolledText widget with some extra key bindings for         entering typical Unicode characters - with umlauts, accents, etc. """     def _ _init_ _(self, master=None, **kwargs):         ScrolledText._ _init_ _(self, master=None, **kwargs)         Diacritical._ _init_ _(self)     def select_all(self, event=None):         self.tag_add(SEL, "1.0", "end-1c")         self.mark_set(INSERT, "1.0")         self.see(INSERT)         return "break"

Discussion

Here is an example of use of these widget classes. We present the example, as usual, with a guard of if _ _name_ _ == '_ _main_ _'; so we can make it part of the module containing the classes and have it run when the module is executed as a "main script":

def test( ):     frame = Frame( )     frame.pack(fill=BOTH, expand=YES)     if os.name == "nt":         frame.option_add("*font", "Tahoma 8")    # Win default, Tk uses other     # The editors     entry = DiacriticalEntry(frame)     entry.pack(fill=BOTH, expand=YES)     text = DiacriticalText(frame, width=76, height=25, wrap=WORD)     if os.name == "nt":         text.config(font="Arial 10")     text.pack(fill=BOTH, expand=YES)     text.focus( )     frame.master.title("Diacritical Editor")     frame.mainloop( ) if _ _name_ _ == "_ _main_ _":     test( )

You might want to remove the keyboard event settings that don't really have much to do with accents and diacritics, (e.g., Ctrl-A, meaning "select all") to some other, separate mixin class. I keep that functionality together with the actual handling of diacritics basically because I always need both features anyway.

Some design choices might be altered, such as my decision to have Ctrl-equal as the way to enter a tilde. I took that path because I just couldn't find a way to make Ctrl-~ work the right way, at least on my Windows machine! Also, depending on which languages you need to support, you might have to add other accents and diacritics, such as a-ring for Swedish, German scharfes-s, Icelandic eth and thorn, and so forth.

See Also

Docs about the unicodedata module in the Library Reference and Python in a Nutshell; information about Tkinter can be obtained from a variety of sources, such as Pythonware's An Introduction to Tkinter, by Fredrik Lundh (http://www.pythonware.com/library), New Mexico Tech's Tkinter Reference (http://www.nmt.edu/tcc/help/lang/python/docs.html), Python in a Nutshell, and various other books.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net