Unicode
wxPython 同时支持 unicode 和 ansi,如果要在程序里使用非英语系的语言,我们最好使用 unicode 进行编码。
Unicode 已经成为一个行业的标准,它使得计算机可以在不同的文字系统里一致地显示和处理文本。unicode 字符编码使用16位来储存字符,而传统的 ASCII 编码则仅使用8位。
在 Python 里,我们可以这样取得 Unicode 编码,以 Лев Николaевич Толстoй Анна Каренина 这个字符串为例子:
u’/u041b/u0435/u0432 /u041d/u0438/u043aa/u0430/u0301
/u0435/u0432/u0438/u0447/u0422/u043e/u043b/u0441o
/u0439 /u0410/u043d/u043d/u0430/u041a/u0430/u0440
/u0435/u043d/u0438/u043d/u0430′
在 Python 命令行下,使用 unicode() 函数取得字符串的 unicode 编码。
import wx
text = u’/u041b/u0435/u0432 /u041d/u0438/u043a/u043e/u043b/u0430/
/u0435/u0432/u0438/u0447 /u0422/u043e/u043b/u0441/u0442/u043e/u0439 /n/
/u0410/u043d/u043d/u0430 /u041a/u0430/u0440/u0435/u043d/u0438/u043d/u0430′
class Unicode(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 150))
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Centre()
self.Show(True)
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.DrawText(text, 50, 50)
app = wx.App()
Unicode(None, -1, ‘Unicode’)
app.MainLoop()
Locale 模块
一个 locale 对象定义了用户使用的语言、国家、数字格式、字母格式、货币格式等等。一个 locale 有下面的格式:
例如,de_AT.utf8 是一个在奥地利使用的德语 UTF8 字符集。
# locale.py
import wx
import time
import locale
class Locale(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 420))
panel = wx.Panel(self, -1)
tm = time.localtime()
font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
us = wx.StaticText(self, -1, ‘United States’, (25, 20))
us.SetFont(font)
wx.StaticLine(self, -1, (25, 50), (200 ,1))
locale.setlocale(locale.LC_ALL, ”)
date = time.strftime(‘%x’, tm)
time_ = time.strftime(‘%X’, tm)
curr = locale.currency(100000)
wx.StaticText(self, -1, ‘date: ‘, (25, 70))
wx.StaticText(self, -1, ‘time: ‘, (25, 90))
wx.StaticText(self, -1, ‘currency: ‘, (25, 110))
wx.StaticText(self, -1, str(date), (125, 70))
wx.StaticText(self, -1, str(time_), (125, 90))
wx.StaticText(self, -1, str(curr), (125, 110))
de = wx.StaticText(self, -1, ‘Germany’, (25, 150))
de.SetFont(font)
wx.StaticLine(self, -1, (25, 180), (200,1))
locale.setlocale(locale.LC_ALL, (‘de_DE’, ‘UTF8′))
date = time.strftime(‘%x’, tm)
time_ = time.strftime(‘%X’, tm)
curr = locale.currency(100000)
wx.StaticText(self, -1, ‘date: ‘, (25, 200))
wx.StaticText(self, -1, ‘time: ‘, (25, 220))
wx.StaticText(self, -1, ‘currency: ‘, (25, 240))
wx.StaticText(self, -1, date, (125, 200))
wx.StaticText(self, -1, time_, (125, 220))
wx.StaticText(self, -1, curr, (125, 240))
de = wx.StaticText(self, -1, ‘Slovakia’, (25, 280))
de.SetFont(font)
wx.StaticLine(self, -1, (25, 310), (200,1))
locale.setlocale(locale.LC_ALL, (’sk_SK’, ‘UTF8′))
date = time.strftime(‘%x’, tm)
time_ = time.strftime(‘%X’, tm)
curr = locale.currency(100000)
wx.StaticText(self, -1, ‘date: ‘, (25, 330))
wx.StaticText(self, -1, ‘time: ‘, (25, 350))
wx.StaticText(self, -1, ‘currency: ‘, (25, 370))
wx.StaticText(self, -1, str(date), (125, 330))
wx.StaticText(self, -1, str(time_), (125, 350))
wx.StaticText(self, -1, str(curr), (125, 370))
self.Centre()
self.Show(True)
app = wx.App()
Locale(None, -1, ‘Locale’)
app.MainLoop()
我们使用 Python 内建的 local 模块来进行本地化的处理。在上面的例子中,我们分别显示美国、德国和斯洛伐克的多种数据格式。
我们设置了一个德国的 locale 对象,LC_ALL 是一个组合值,它包括了 LC_TIME,LC_MONETARY,LC_NUMERIC 等等。
time_ = time.strftime(‘%X’, tm)
curr = locale.currency(100000)
函数使用对应的 locale 对象。
世界时(World Time)
因为存在时区,所以世界上的时间是不尽相同的。wxPython 通过 wx.DateTime 对象来处理这个问题,它表示了一个绝对时刻。
import wx
import time
class WorldTime(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(270, 280))
self.panel = wx.Panel(self, -1)
self.panel.SetBackgroundColour(‘#000000′)
font = wx.Font(12, wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ‘Georgia’)
self.dt = wx.DateTime()
self.tokyo = wx.StaticText(self.panel, -1,
self.dt.FormatTime() , (20, 20))
self.tokyo.SetForegroundColour(‘#23f002′)
self.tokyo.SetFont(font)
self.moscow = wx.StaticText(self.panel, -1,
self.dt.FormatTime() , (20, 70))
self.moscow.SetForegroundColour(‘#23f002′)
self.moscow.SetFont(font)
self.budapest = wx.StaticText(self.panel, -1,
self.dt.FormatTime() , (20, 120))
self.budapest.SetForegroundColour(‘#23f002′)
self.budapest.SetFont(font)
self.london = wx.StaticText(self.panel, -1,
self.dt.FormatTime() , (20, 170))
self.london.SetForegroundColour(‘#23f002′)
self.london.SetFont(font)
self.newyork = wx.StaticText(self.panel, -1,
self.dt.FormatTime() , (20, 220))
self.newyork.SetForegroundColour(‘#23f002′)
self.newyork.SetFont(font)
self.OnTimer(None)
self.timer = wx.Timer(self)
self.timer.Start(1000)
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.Centre()
self.Show(True)
def OnTimer(self, evt):
now = self.dt.Now()
self.tokyo.SetLabel(‘Tokyo: ‘ + str(now.Format((‘%a %T’),
wx.DateTime.GMT_9)))
self.moscow.SetLabel(‘Moscow: ‘ + str(now.Format((‘%a %T’),
wx.DateTime.MSD)))
self.budapest.SetLabel(‘Budapest: ‘ + str(now.Format((‘%a %T’),
wx.DateTime.CEST)))
self.london.SetLabel(‘London: ‘ + str(now.Format((‘%a %T’),
wx.DateTime.WEST)))
self.newyork.SetLabel(‘New York: ‘ + str(now.Format((‘%a %T’),
wx.DateTime.EDT)))
app = wx.App()
WorldTime(None, -1, ‘World Time’)
app.MainLoop()
在上面的例子中,我们显示了东京、莫斯科、布达佩斯、伦敦和纽约的当前时间。
创建一个 wx.DateTime 对象。
取得当前的绝对时间。
格式化时间字符串。%a 表示使用星期的缩写格式;%T 表示使用 %H:%M:%S 格式显示时间;wx.DateTime.GMT_9 表示时区,GMT_9 是日本的时区。
排序(Sorting)
注意,本地化的设置会影响到字符串的排序。
# collate.py
import wx
import locale
ID_SORT = 1
words = [u'Sund', u'S/xe4bel', u'S/xfcnde', u'Schl/xe4fe', u'Sabotage']
class Collate(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(300, 220))
panel = wx.Panel(self, -1)
hbox = wx.BoxSizer(wx.HORIZONTAL)
self.listbox = wx.ListBox(panel, -1)
for i in words:
self.listbox.Append(i)
hbox.Add(self.listbox, 1, wx.EXPAND | wx.ALL, 20)
btnPanel = wx.Panel(panel, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
new = wx.Button(btnPanel, ID_SORT, ‘Sort’, size=(90, 30))
self.Bind(wx.EVT_BUTTON, self.OnSort, id=ID_SORT)
vbox.Add((-1, 20))
vbox.Add(new)
btnPanel.SetSizer(vbox)
hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20)
panel.SetSizer(hbox)
locale.setlocale(locale.LC_COLLATE, (‘de_DE’, ‘UTF8′))
self.Centre()
self.Show(True)
def OnSort(self, event):
self.listbox.Clear()
words.sort( lambda a,b: locale.strcoll(a, b) )
for i in words:
self.listbox.Append(i)
app = wx.App()
Collate(None, -1, ‘Collate’)
app.MainLoop()
在上面的例子中,我们对5个德文单词进行排序。默认的 sort() 方法排序后得到的结果为:Sabotage, Schläfe, Sund, Säbel, Sünde。但这个结果是错误的,因为是德语里,ä 字符是排第一的。要得到正确的排序,我们必须使用 locale。
这里,我们设置为德语。LC_COLLATE 处也可以使用 LC_COLLATE。
我们向 sort() 方法提供一个指定的比较方法,这里是一个匿名的方法。strcoll() 方法跟 sort() 方法想像,也是比较两个字符串,然后返回-1,0,1,但会根据具体的 locale 进行比较。
简单翻译(Simple translation)
在下面的例子中,我们将会演示一个简单的翻译过程。
我们有翻译的方式,使用 GNU gettext 或者 wxPython 的 catalogs。而两者是相互兼容。
wxPython 有一个 wx.Locale 类,它可以简单的使用 message catalogs。如果我们想翻译一个字符串为德语,首先需要确认系统已经提供对德语的支持。下面的命令(*NIX 系统 命令)可以查看当前系统支持的语言:
C
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_LU.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZW.utf8
POSIX
sk_SK.utf8
如上所示,在我的系统里,提供了对英语、德语、斯洛伐克语的支持。utf8 表示系统使用 utf8 对字符串进行编码。
import wx
class Translation(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(220, 100))
panel = wx.Panel(self, -1)
mylocale = wx.Locale()
mylocale.AddCatalogLookupPathPrefix(‘.’)
mylocale.AddCatalog(’simple_de’)
_ = wx.GetTranslation
wx.StaticText(panel, -1, _(“hello”), (10, 10))
#wx.StaticText(panel, -1, wx.GetTranslation(‘hello’), (10, 10))
self.Centre()
self.Show(True)
app = wx.App()
Translation(None, -1, ‘Translation’)
app.MainLoop()
下面我们创建一个 PO 文件,这是用于翻译的文本文件。
这里我们使用 pygettext 命令来创建 PO 文件。pygettext 的具体使用请查看 GNU gettext 手册。
编辑 simple_de.po 文件,指定其字符集为 utf-8。
msgid “hello”
msgstr “Grüß Gott”
这里,我们提供一个对 Hello 的翻译。
最后,我们必须创建一个二进制的 message catalog。
使用 msgfmt 命令来生成一个 mo 文件。