基于xrced的i18n的实现

周海汉 /文

2010.2.17

 

我以前一篇文章《wxpython 使用 XRCed创建界面 》,提到如何用xrced创建界面以及它支持gettext的i18n,但并没有具体的i18n的实现。本文举例基于xrced的i18n的实现。

参考文档中有金庆的关于xrc的i18n的实现。不过,他在2007年末是完全自己实现装载xrc,那么事件,控件的绑定都需要自己实现。而xrced自动生成的代码可以自动实现装载和绑定,我的实现是基于自动的代码之上的i18n。应该比金庆的更简单快捷。尤其是界面复杂而又经常变动时。

所以本文可以算是他的文章的一个有益补充与更新。

一、使用xrced建立一个简单框架

保存为xrci18n.xrc,如下:

<?xml version="1.0" ?> <resource> <object class="wxFrame" name="xrcframe"> <object class="wxTextCtrl" name="xrctext"> <size>200,200</size> <value>hello,world</value> <mce:style><!-- wxTE_MULTILINE --></mce:style><style mce_bogus="1">wxTE_MULTILINE</style> <XRCED> <events>EVT_TEXT_ENTER</events> </XRCED> </object> <size>200,200</size> <title>hello</title> </object> </resource>

 

二、使用xrced生成py代码

在“generate python"对话框里,一定选上"generate gettext strings".生成xrci18n_xrc.py。

# This file was automatically generated by pywxrc. # -*- coding: UTF-8 -*- import wx import wx.xrc as xrc __res = None def get_resources(): """ This function provides access to the XML resources in this module.""" global __res if __res == None: __init_resources() return __res class xrcxrcframe(wx.Frame): #!XRCED:begin-block:xrcxrcframe.PreCreate def PreCreate(self, pre): """ This function is called during the class's initialization. Override it for custom setup before the window is created usually to set additional window styles using SetWindowStyle() and SetExtraStyle(). """ pass def i18n_install(self, localdir, languages): self.lang = wx.Locale() self.lang.Init(wx.LANGUAGE_CHINESE_SIMPLIFIED) self.lang.AddCatalogLookupPathPrefix(localdir) self.lang.AddCatalog('messages') gettext.install('messages', localedir=localdir, unicode=True) #!XRCED:end-block:xrcxrcframe.PreCreate def __init__(self, parent): # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation) pre = wx.PreFrame() self.PreCreate(pre) get_resources().LoadOnFrame(pre, parent, "xrcframe") self.PostCreate(pre) # Define variables for the controls, bind event handlers self.Bind(wx.EVT_TEXT_ENTER, self.OnText_enter_xrctext, id=xrc.XRCID('xrctext')) #!XRCED:begin-block:xrcxrcframe.OnText_enter_xrctext def OnText_enter_xrctext(self, evt): # Replace with event handler code print "OnText_enter_xrctext()" #!XRCED:end-block:xrcxrcframe.OnText_enter_xrctext # ------------------------ Resource data ---------------------- def __init_resources(): global __res __res = xrc.EmptyXmlResource() __res.Load('xrci18n.xrc') # ----------------------- Gettext strings --------------------- def __gettext_strings(): # This is a dummy function that lists all the strings that are used in # the XRC file in the _("a string") format to be recognized by GNU # gettext utilities (specificaly the xgettext utility) and the # mki18n.py script. For more information see: # http://wiki.wxpython.org/index.cgi/Internationalization def _(str): pass _("hello,world") _("hello")

三、增加对i18n的支持代码

新建一个文件xrci18nfrm.py,继承自动生成的xrcxrcframe框架类,用于重载方法,事件的实现。而xrci18n_xrc.py每次修改xrc界面都会自动生成,导致你的实现可能丢失,所以要在新文件中继承并实现。

 

#!/bin/env python # -*- coding: utf8 -*- # Author: ablozhou # E-mail: [email protected] # # Copyright 2010 ablozhou # File: xrci18nfrm.py import wx import wx.xrc as xrc import xrci18n_xrc import gettext class xrcframe(xrci18n_xrc.xrcxrcframe): def PreCreate(self, pre): pass def i18n_install(self, localdir, languages): self.lang = wx.Locale() self.lang.Init(wx.LANGUAGE_CHINESE_SIMPLIFIED) self.lang.AddCatalogLookupPathPrefix(localdir) self.lang.AddCatalog('messages') gettext.install('messages', localedir=localdir, unicode=True) def __init__(self, parent): self.i18n_install('locale',['zh_CN']) xrci18n_xrc.xrcxrcframe.__init__(self,parent) def OnText_enter_xrctext(self, evt): print "xrcframe OnText_enter_xrctext()"

 

这里增加了对i18n的支持。实现了一个函数i18n_install. 并在__init__方法中调用。

wx的i18n不是单纯的gettext就可以的。必须使用wx.Locale(). 代码中将其语言初始化为wx.LANGUAGE_CHINESE_SIMPLIFIED,即中文简体。

设置翻译语言路径,增加类别。最后使用gettext安装该语言。

此处可以再实现为配置文件,以及根据系统环境自动选择语言。

 

四、处理xrc资源

gettext不能直接处理xrc,只能处理自动生成的xrci18n_xrc.py。

4.1 安装gettext

其实python自带gettext处理模块,但我还是选择安装gettext和msgfmt,方便使用。

sudo agp-get install gettext


4.2 生成pot文件和mo文件

zhouhh@zhouhh-home:~$ cd xrci18n/ zhouhh@zhouhh-home:~/xrci18n$ xgettext xrci18n xrci18n.py xrci18n.xrc xrci18n_xrc.py zhouhh@zhouhh-home:~/xrci18n$ xgettext xrci18n_xrc.py zhouhh@zhouhh-home:~/xrci18n$ ls messages.po xrci18n.py xrci18n.xrc xrci18n_xrc.py zhouhh@zhouhh-home:~/xrci18n$ gedit messages.po zhouhh@zhouhh-home:~/xrci18n$ msgfmt.py messages.po msgfmt.py: command not found zhouhh@zhouhh-home:~/xrci18n$ msgfmt messages.po zhouhh@zhouhh-home:~/xrci18n$ ls locale messages.mo messages.po xrci18n.py xrci18n.xrc xrci18n_xrc.py

 

其中messages.po是xgettext提取出来的。如下:

# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION/n" "Report-Msgid-Bugs-To: /n" "POT-Creation-Date: 2010-02-17 09:44+0800/n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE/n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>/n" "Language-Team: LANGUAGE <[email protected]>/n" "MIME-Version: 1.0/n" "Content-Type: text/plain; charset=CHARSET/n" "Content-Transfer-Encoding: 8bit/n" #: xrci18n_xrc.py:77 msgid "hello,world" msgstr "" #: xrci18n_xrc.py:78 msgid "hello" msgstr ""

可以看到hello和hello,world两个资源。

修改后如下:

# XRC I18N file # Copyright (C) 2010 ablo zhou # This file is distributed under the same license as the PACKAGE package. # ablo zhou <[email protected]>,2010. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION/n" "Report-Msgid-Bugs-To: /n" "POT-Creation-Date: 2010-02-17 08:36+0800/n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE/n" "Last-Translator: ablo zhou <[email protected]>/n" "Language-Team: zh_CN <[email protected]>/n" "MIME-Version: 1.0/n" "Content-Type: text/plain; charset=UTF-8/n" "Content-Transfer-Encoding: UTF-8/n" #: xrci18n_xrc.py:78 msgid "hello,world" msgstr "你好,世界" #: xrci18n_xrc.py:79 msgid "hello" msgstr "你好程序"

 

调用msgfmt生成mo文件:

zhouhh@zhouhh-home:~/xrci18n$ msgfmt messages.po

 

4.3 遵循gettext格式,新建locale目录

下面有各种语言如en_US,zh_CN,每种语言下面新建LC_MESSAGES目录,下面放真正的翻译mo文件。

zhouhh@zhouhh-home:~/xrci18n$ ls locale
en_US  zh_CN
zhouhh@zhouhh-home:~/xrci18n$ ls locale/zh_CN
LC_MESSAGES
zhouhh@zhouhh-home:~/xrci18n$ ls locale/zh_CN/LC_MESSAGES/
messages.mo

再将生成的messages.mo拷贝到locale/zh_CN/LC_MESSAGES/目录下。

 

五、新建测试文件xrci18n.py

#!/bin/env python # -*- coding: utf8 -*- # Author: ablozhou # E-mail: [email protected] # # Copyright 2010 ablozhou # File:xrci18n.py import wx import xrci18nfrm class XrcApp(wx.App): def OnInit(self): '''Init Xrc App.''' self.mainfrm = xrci18nfrm.xrcframe(parent = None) self.SetTopWindow(self.mainfrm) self.mainfrm.Show() return True def Exit(self): pass def main(): app = XrcApp() app.MainLoop() if __name__ == '__main__': main()

继承wx.App是为了程序以后有更多的扩展。实现其OnInit和OnExit方法。

 

六、执行

python xrci18n.py

看到程序已经变成中文界面。由于csdn关闭传图,故不能展示效果。

 

七、参考:

社区讨论:http://bbs.pythonid.com/viewthread.php?tid=179

wxpython官网:http://wiki.wxpython.org/XRCAndI18N

相关ppt:http://yergler.net/talks/desktopapps_uk/

wxpython官网:http://wiki.wxpython.org/UsingXmlResources

金庆的相关文章:http://blog.csdn.net/jq0123/archive/2007/12/17/1943440.aspx

你可能感兴趣的:(python,function,File,语言,resources,wxPython)