wxPython中XRC文件i18n示例
(转载请注明来源于金庆的专栏)
简介
XRC文件是XML格式的界面定义文件,
用于在wxWidgets/wxPython中生成界面。
i18n(Internationaliztion)是指国际化,对资源进行翻译。
wxPython中XRC文件i18n有两种方法,
一种是使用多个XRC文件,每个语种一个XRC,
另一种是只用一个XRC文件,各个语言使用一个mo翻译文件。
本文是按照
“
wxPython中XRC文件对 i18N的支持”
一文的指示,演示使用mo文件对XRC文件进行国际化翻译。
创建XRC
用xrced创建一个text.xrc。只有一个空白窗口。
窗口标题"frame1"是待翻译字符串。
<?xml version="1.0" encoding="utf-8"?><resource> <object class="wxFrame" name="FRAME1"> <title>test frame</title> </object></resource>
显示窗口
写一个简单的python程序test.py,装入该窗口并显示。
import wximport wx.xrc as xrcclass MyApp(wx.App): def OnInit(self): self.res = xrc.XmlResource(r"./test.xrc") self.frame_1 = self.res.LoadFrame(None, "FRAME1") self.frame_1.Show() return 1 # End of OnInit(). # End of class MyApp.if __name__ == "__main__": app = MyApp(0) app.MainLoop() 运行如下:
提取并翻译资源
先生成一个带资源的Python代码frame1.py,xrced可以生成python代码,
选中gettext支持,生成的文件包含资源中的字串符。
# This file was automatically generated by pywxrc, do not edit by hand.# -*- coding: UTF-8 -*-import wximport wx.xrc as xrc__res = Nonedef get_resources(): """ This function provides access to the XML resources in this module.""" global __res if __res == None: __init_resources() return __resclass xrcFRAME1(wx.Frame): 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 __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, "FRAME1") self.PostCreate(pre) # create attributes for the named items in this container# ------------------------ Resource data ----------------------def __init_resources(): global __res __res = xrc.EmptyXmlResource() __res.Load('test.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 _("test frame")该生成的程序只是为了作为xgettext的输入,
> xgettext frame1.py
输出message.po。
编辑该po文件,指定charset并翻译"test frame",如下:
# 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.#msgid ""msgstr """Project-Id-Version: PACKAGE VERSION\n""POT-Creation-Date: 2007-12-17 10:58+0800\n""PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n""Last-Translator: FULL NAME <EMAIL@ADDRESS>\n""Language-Team: LANGUAGE <LL@li.org>\n""MIME-Version: 1.0\n""Content-Type: text/plain; charset=gb2312\n""Content-Transfer-Encoding: 8bit\n"#: frame1.py:55msgid "test frame"msgstr "测试窗口"然后用msgfmt,将messages.po编译成messages.mo。
> msgfmt messages.po
创建.\locale\zh_CN\LC_MESSAGES\目录,并复制messages.mo到此。
翻译XRC
为了装入XRC时翻译字符串,需要指定wx.Locale,让Locale来翻译界面中的资源。
并在XmlResource创建时,指定
flags=XRC_USE_LOCALE domain="messages"其中flags缺省值如此,而domain必须显示指定。
test.py更改如下:
import wximport wx.xrc as xrcL = wx.Locale()class MyApp(wx.App): def OnInit(self): L.Init(wx.LANGUAGE_CHINESE_SIMPLIFIED) L.AddCatalogLookupPathPrefix(r'./locale') L.AddCatalog('messages') self.res = xrc.XmlResource(r"./test.xrc", domain = "messages") self.frame_1 = self.res.LoadFrame(None, "FRAME1") self.frame_1.Show() return 1 # End of OnInit(). # End of class MyApp.if __name__ == "__main__": app = MyApp(0) app.MainLoop()运行结果:
总结
千言万语,不如实际做个例子。
与wxPython一样,其它C语言编写的第三方python模块在i18n上并不能利用python的gettext模块,
所以解决之道是:所有输入都是翻译好的,或者,该扩展模块本身支持i18n。
http://www.cppblog.com/Files/jinq0123/xrci18n.zip