26 2月 2010

[wxPython] 實作多國語言MUI by GetText

wxPython提供了方便的支援多國語言API,結合GNU GetText project,使用上很是方便。
由GetText parse 檔案後,建出PO檔然後轉成MO檔,就可以給wxPython讀取使用。



首先,先撰寫wxPython的code

#!/usr/bin/python

import wx
_ = wx.GetTranslation

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)

        wx.StaticText(panel, -1, _("Hello"), (10, 10))
        
        self.Centre()
        self.Show(True)

app = wx.App()

mylocale = wx.Locale()
mylocale.AddCatalogLookupPathPrefix('.')
mylocale.AddCatalog('CHT') #Use CHT.mo

Translation(None, -1, 'Translation')
app.MainLoop()

執行畫面


使用 wx.Locale 的 AddCatalog(),wxPython就會去搜尋目前的目錄、系統目錄,或是透過AddCatalogLookupPathPrefix()指定的路徑。
然後將 wx.GetTranslation 指定成 _ ,這樣子我們只要對想翻譯的字串"Hello"改成_("Hello")就可以了。
Tip: GetText建立PO檔時,只會針對_("")裡面的字串做處理。

接下來必須下載 GetText 的 Tool 才能建立翻譯字串所需的PO檔跟MO檔。
安裝完GetText之後,就有一些執行檔可以使用了,以下介紹幾個最需要用到的:
    xgettext.exe
    將 input 檔案內的翻譯字串收集後,儲存成PO檔。
    xgettext [option] [inputfile] ...
    'inputfile ...' : 處理此file
    '-f file', '--files-from=file' :處理file內的儲存的file name
    '-d name', '--default-domain=name' : 輸出檔名為name.po

    因此,我將上面的wxPython檔案存為test.py
    xgettext  --default-domain=test  test.py
    之後就會輸出一個test.po的檔案,檔案的內容為下列
    # 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-26 16:31+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=CHARSET\n"
    "Content-Transfer-Encoding: 8bit\n"
    
    #: ..\test.py:12
    msgid "Hello"
    msgstr ""

    現在就可以修改 test.po 檔,可以在裡面打入想翻譯的字串,比如將"Hello"翻譯成中文,儲存成CHT.po,將"Hello"翻譯成英文,儲存成ENU.po
    通常翻譯成非英文的語言,就要將PO檔的 encoding 方式改成UTF-8的格式儲存,才能正確存取。所以要將檔案轉成UTF-8編碼(可以用Notepad++,轉成UTF-8檔首無BOM),然後改"Content-Type: text/;lain; charset=CHARSET\n",將CHARSET改成utf-8
    # 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-26 16:31+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=utf-8\n" #charset
    "Content-Transfer-Encoding: 8bit\n"
    
    #: ..\test.py:12
    msgid "Hello"
    msgstr "哈囉~"


    msgmerge.exe
    將兩個PO檔,進行Merge的動作,通常是用在PO檔更新時。
    msgmerge [option] def.po ref.po
    'def.po' : 原本已經翻譯過的PO檔
    'ref.po' : 新建立好的PO檔
    '-U', '--update' : 如果def.po已經是最新的,就不做事
    所以,假如我們在test.py裡,加了一個新字串_("Sudoku")後,先執行xgettext產生新的PO檔,再執行msgmerge做merge的動作
    xgettext  --default-domain=test_new  test.py
    msgmerge  --update test.po  test_new.po


    msgfmt.exe
    將PO檔轉成MO檔
    msgfmt [option] filename.po
    '- o file', '--output-file=file' : 指定輸出的檔名
    msgfmt  --output-file=CHT.mo  test.po

    最後,就將中文翻譯的CHT.mo放在test.py檔同個目錄下,執行後應該就會顯示中文了。

    執行畫面

      沒有留言: