金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
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 wx
import wx.xrc as xrc

class 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 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 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:55
msgid "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 wx
import wx.xrc as xrc

L = 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

posted on 2007-12-17 12:22 金庆 阅读(1991) 评论(0)  编辑 收藏 引用 所属分类: 6. Python

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理