Thus spoketh [email protected]
unto us on Fri, 10 Dec 2010 10:23:37 -0500:
> I noticed there are a lot of non-US developers on this list. I'm
> looking for tips on using Tkinter in non-US locales.
>
> In particular:
>
> 1. Are there any Unicode or font specific issues to be concerned
> about?
>
> 2. Are you using the locale module to control how you display or
> parse data moving into and out of Entry widgets? (has anyone
> wrapped the Entry widget with locale aware code?)
>
> 3. Are you using gettext with Tkinter and if so, are there any
> tips or traps to watch for? (I think gettext integration should
> be seamless, but didn't think it would hurt to confirm this)
I haven't used python3 yet, I think there aren't separate unicode and byte
string types anymore (can someone confirm this?) which will make things
probably straightforward.
In python-2.x using gettext can be quite a pain in the neck. To be on the
safe side, I always use gettext with unicode=True and take care that any
string that is passed to tk is converted into unicode first and any
string that python receives from Tk is converted into a byte string
before processing it (the odd thing is that sometimes you don't know in
advance if you get a byte string or unicode). When dealing with gettext
I always use a module with some convenience methods to make this easier:
##################################################
sysencoding = _sysencoding().lower()
def fsdecode(input, errors='strict'):
'''Fail-safe decodes a string into unicode.'''
if not isinstance(input, unicode):
try:
return unicode(input, sysencoding, errors)
except UnicodeError:
print 'Unicode Error while decoding string:', input
return unicode(input, sysencoding, 'replace')
return input
def fsencode(input, errors='strict'):
'''Fail-safe encodes a unicode string into system default encoding.'''
if isinstance(input, unicode):
try:
return input.encode(sysencoding, errors)
except UnicodeError:
print 'Unicode Error while encoding string:', input
return input.encode(sysencoding, 'replace')
return input
class UnicodeVar(Tkinter.StringVar):
def __init__(self, master=None, errors='strict'):
self.errors = errors
Tkinter.StringVar.__init__(self, master)
def get(self):
"""Return value of variable as unicode string."""
value = self._tk.globalgetvar(self._name)
if isinstance(value, basestring):
return fsdecode(value, self.errors)
return fsdecode(value, self.errors)
def set(self, value):
"""Set the variable to VALUE."""
return self._tk.globalsetvar(self._name, fsencode(value, self.errors))
##################################################
The tricky thing here is of course the _sysencoding() function that
should detect the system default encoding. My function does basically
the same as the idlelib.IOBinding module, so you could replace it with
def _sysencoding():
import idlelib
return idlelib.IOBinding.encoding
The fsdecode and fsencode functions proved to be quite handy, in situations
where you don't know if you have a byte string or unicode I can simply do for
example:
message = _('Unsupported file type') + u':\n"%s"' % fsdecode(fname)
(if fname is e.g. returned from a tkFileDialog it is unicode in case it
contains non-ascii characters, otherwise a byte string; otoh, the same filename
returned by os.listdir() is always a byte string!)
Regards
Michael
.-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-.
"... freedom ... is a worship word..."
"It is our worship word too."
-- Cloud William and Kirk, "The Omega Glory", stardate unknown
_______________________________________________
Tkinter-discuss mailing list
[email protected]
http://mail.python.org/mailman/listinfo/tkinter-discuss