一、什么是python的国际化(I18N)

有关I18N,百度上解释一大堆,个人比较喜欢这个说法。

i18n是 Internationalization 这个英文的简写,因为Internationalization这个单词去掉头尾的i和n刚好还剩下18个字符,意思是国际化。

再通俗讲就是程序的多语言:程序提供多语言功能,用户选择中文,则切换到中文界面,选择英文,则切换到英文界面,甚至是俄文、西班牙文、繁体等等。

具体到本文的python下的wxpython国际化,是指在python开发环境下,实现windows程序(基于wxpython开发)多语言功能。

很简单也很普世的需求吧,但在实现的过程中间其实遇到了很多困难,主要原因还是两个:1、百度资料太少,2、英文水平又一般。

经过几天的研究,各种google,结合wxpython下的Editra示例程序(在C:\Python27\Lib\site-packages\wx-3.0-msw\wx\tools\Editra目录下),最后总结出来一个如下的简化用法。

特别说明:本方案适合小白用户,只需要实现,不需要了解国际化的具体实现方法。

二、版本说明

Python    : 2.7.11rc1 (v2.7.11rc1:82dd9545bd93, Nov 21 2015, 23:25:27) [MSC v.1500 64 bit (AMD64)]
pyOpenSSL : 16.0.0 (OpenSSL 1.0.2g  1 Mar 2016)
Platform  : Windows-10-10.0.10586
wx.VERSION_STRING:3.0.2.0

三、wxpython程序代码说明

程序如下:上面是英文界面,下面是中文界面。

1、主程序 eUpdateMainFrame.py

程序很简单,全部是使用wx的配套界面工具wxFormBuilder自动生成,红色字体部分就是用来实现多语言功能的代码。

a.修改__builtin__.__dict__,引入_()函数到系统内建模块中,使_()等同于wx.GetTranslation()。

b.调用wx.locale(wx.LANGUAGE_ENGLISH),声明使用英语界面,若是要改成简体中文,则是wx.LANGUAGE_CHINESE_SIMPLIFIED

c.调用wx.locale().AddCatalogLookupPathPrefix('local'),声明语言包放在程序目录下local子目录下。

d.调用wx.locale().AddCatalog('autoupdate') 声明语言文件名字autoupdate,注意这个函数一定得是返回True才是调用成功。

"""Subclass of MainFrame, which is generated by wxFormBuilder."""

import wx
import eupdate #把_()变成系统方法
import __builtin__
__builtin__.__dict__['_'] = wx.GetTranslation # Implementing MainFrame
class eUpdateMainFrame( eupdate.MainFrame ):
def __init__( self, parent ):
locale = None
locale = wx.Locale(wx.LANGUAGE_ENGLISH)
if locale.IsOk():
locale.AddCatalogLookupPathPrefix('locale')
ibRet = locale.AddCatalog('autoupdate') eupdate.MainFrame.__init__( self, parent ) # init the programe
#实例化APP,因为wxformbuilder只提供界面布局,所以需要我们自己对代码进行构架
app = wx.App()
#frame的实例
frame = eUpdateMainFrame(None)
frame.Show();
#wxpython的启动函数
app.MainLoop()

2、窗口布局代码 eupdate.py(用wxFormBuilder画的。)

a.注意所有需要自动翻译的文本都需要用前文定义的_()函数扩起来。

譬如:title=_(u"自动升级"), 本来写法是:title=u"自动升级"。

# -*- coding: utf-8 -*- 

###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
########################################################################### import wx
import wx.xrc
import wx.richtext ###########################################################################
## Class MainFrame
########################################################################### class MainFrame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = _(u"自动升级"), pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.STAY_ON_TOP|wx.TAB_TRAVERSAL ) self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNTEXT ) )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) )
self.SetToolTipString( _(u"自动升级程序") ) sizer = wx.BoxSizer( wx.VERTICAL ) self.m_tip = wx.StaticText( self, wx.ID_ANY, _(u"MyLabel"), wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT )
self.m_tip.Wrap( -1 )
self.m_tip.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_CAPTIONTEXT ) )
self.m_tip.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ) ) sizer.Add( self.m_tip, 1, wx.ALIGN_TOP|wx.ALL|wx.EXPAND, 5 ) self.m_desc = wx.richtext.RichTextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_AUTO_URL|wx.TE_READONLY|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
sizer.Add( self.m_desc, 2, wx.ALIGN_TOP|wx.ALL|wx.EXPAND, 5 ) self.m_gauage_process = wx.Gauge( self, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL|wx.GA_SMOOTH )
self.m_gauage_process.SetValue( 0 )
self.m_gauage_process.SetMinSize( wx.Size( -1,25 ) ) sizer.Add( self.m_gauage_process, 0, wx.ALL|wx.EXPAND, 5 ) sizebtn = wx.BoxSizer( wx.HORIZONTAL ) sizebtn.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 ) self.m_btnok = wx.Button( self, wx.ID_ANY, _(u"升级&O"), wx.DefaultPosition, wx.DefaultSize, wx.BU_BOTTOM )
self.m_btnok.SetDefault()
self.m_btnok.SetMinSize( wx.Size( -1,25 ) ) sizebtn.Add( self.m_btnok, 0, wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT|wx.ALL|wx.EXPAND, 2 ) self.m_btncacel = wx.Button( self, wx.ID_ANY, _(u"取消升级&C"), wx.DefaultPosition, wx.DefaultSize, wx.BU_BOTTOM )
self.m_btncacel.SetMinSize( wx.Size( -1,25 ) ) sizebtn.Add( self.m_btncacel, 0, wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT|wx.ALL|wx.EXPAND, 2 ) sizer.Add( sizebtn, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) self.SetSizer( sizer )
self.Layout() self.Centre( wx.BOTH ) # Connect Events
self.m_btncacel.Bind( wx.EVT_BUTTON, self.close ) def __del__( self ):
pass # Virtual event handlers, overide them in your derived class
def close( self, event ):
pass

四、I18N多语言原理

1、多语言原理

前面的多语言功能代码,提到_()函数等同于wx.translation方法,其核心原理:

读取指定的语言文件,依据原始文本查找对应的翻译文本。譬如_('自动升级')翻译成英文就是'auto update'。

2、多语言文件

语言文件主要是指三个文件:.mo文件,.po文件,.pot文件,百度上资料也很多,具体可以查看这个网址:http://shandian.biz/278.html

这里简单说明如下:

1、pot文件,原始的语言文件,提取自源代码,读取所有的_()括弧内的文本,按一定规则生成这个文件。

2、po文件,是从原始pot文件对应的翻译文件,生成这个文件需要用到一个poedit软件。

3、mo文件,是编译后的po文件,程序可以直接读取,个人理解这么设置的目的是提高加载效率。

这里说明一点,这个pot、po、mo文件是一个通用规则,不是python首创的,很多著名的开发语言都支持上述i18n解决方案。

五、python下语言文件生成方法

如前文所述,语言文件主要有三步:

1.提取文本,生成pot文件,代码如下:

python C:\Python27\Tools\i18n\pygettext.py -a -d eupdate -o eupdate.pot -p d:\python\eupdate\locale d:\python\eupdate

a、调用C:\Python27\Tools\i18n\下的pygettext.py脚本;

b、提取源码目录d:\python\eupdate中,所有的py中的_()中文本,生成pot文件。

2.使用poEdit生成po文件。

a、这里提到的外部工具poEDIT有中文版本,请自行到https://poedit.net去下载.

b、读取pot文件,翻译生成po文件,这个需要手动逐条完成 。

3.生产mo文件

python C:\Python27\Tools\i18n\msgfmt.py d:\python\eupdate\locale\en\LC_MESSAGES\eupdate.po

a、调用C:\Python27\Tools\i18n\下的msgfmt.py脚本;

b、读取步骤2生成的d:\python\eupdate\locale\en\LC_MESSAGES\eupdate.po文件,生成mo文件。

但是,但是,经过研究发现poEDIT最新版本,集成了上述三个功能,而且实测该功能支持python代码。

具体步骤请各位自行琢磨,中文菜单相对还是比较简单的。

六、语言文件目录及命名规则

前面介绍了语言文件原理,其实语言文件还有一个特定的命名、存放目录规则,下面实例说明:

#1、locale目录默认在源码目录下,名字可以自定义。
D:\python\eupdate\locale>dir /S
驱动器 D 中的卷没有标签。
卷的序列号是 36D9-CDC7 #2、en目录默认在locale下,名字有规则,与源码中配置对应。
D:\python\eupdate\locale 的目录
2016-10-03 21:00 <DIR> .
2016-10-03 21:00 <DIR> ..
2016-10-03 21:01 <DIR> en
2016-10-03 20:58 995 eupdate.pot
1 个文件 995 字节

#3、en目录下的LC_MESSAGES,名字不能改
D:\python\eupdate\locale\en 的目录
2016-10-03 21:01 <DIR> .
2016-10-03 21:01 <DIR> ..
2016-10-03 21:03 <DIR> LC_MESSAGES
0 个文件 0 字节

#4、mo、po文件必须放在LC_MESSAGES目录下,名字可以改,也需与代码配合
D:\python\eupdate\locale\en\LC_MESSAGES 的目录
2016-10-03 21:03 <DIR> .
2016-10-03 21:03 <DIR> ..
2016-10-03 21:03 832 autoupdate.mo
2016-10-03 21:03 1,136 autoupdate.po
2 个文件 1,968 字节 所列文件总数:
3 个文件 2,963 字节
8 个目录 116,639,555,584 可用字节

1、在源码目录下有locale子目录,对应代码wx.locale().AddCatalogLookupPathPrefix('locale'),目录名名可以修改。

2、locale下子目录en,对应代码wx.Locale(wx.LANGUAGE_ENGLISH),目录名与语言有一个对照关系规则(附一个对照关系表)。

('LANGUAGE_ABKHAZIAN', 2, u'ab')
('LANGUAGE_AFAR', 3, u'aa')
('LANGUAGE_AFRIKAANS', 4, u'af_ZA')
('LANGUAGE_ALBANIAN', 5, u'sq_AL')
('LANGUAGE_AMHARIC', 6, u'am')
('LANGUAGE_ARABIC', 7, u'ar')
('LANGUAGE_ARABIC_ALGERIA', 8, u'ar_DZ')
('LANGUAGE_ARABIC_BAHRAIN', 9, u'ar_BH')
('LANGUAGE_ARABIC_EGYPT', 10, u'ar_EG')
('LANGUAGE_ARABIC_IRAQ', 11, u'ar_IQ')
('LANGUAGE_ARABIC_JORDAN', 12, u'ar_JO')
('LANGUAGE_ARABIC_KUWAIT', 13, u'ar_KW')
('LANGUAGE_ARABIC_LEBANON', 14, u'ar_LB')
('LANGUAGE_ARABIC_LIBYA', 15, u'ar_LY')
('LANGUAGE_ARABIC_MOROCCO', 16, u'ar_MA')
('LANGUAGE_ARABIC_OMAN', 17, u'ar_OM')
('LANGUAGE_ARABIC_QATAR', 18, u'ar_QA')
('LANGUAGE_ARABIC_SAUDI_ARABIA', 19, u'ar_SA')
('LANGUAGE_ARABIC_SUDAN', 20, u'ar_SD')
('LANGUAGE_ARABIC_SYRIA', 21, u'ar_SY')
('LANGUAGE_ARABIC_TUNISIA', 22, u'ar_TN')
('LANGUAGE_ARABIC_UAE', 23, u'ar_AE')
('LANGUAGE_ARABIC_YEMEN', 24, u'ar_YE')
('LANGUAGE_ARMENIAN', 25, u'hy')
('LANGUAGE_ASSAMESE', 26, u'as')
('LANGUAGE_ASTURIAN', 27, u'ast')
('LANGUAGE_AYMARA', 28, u'ay')
('LANGUAGE_AZERI', 29, u'az')
('LANGUAGE_AZERI_CYRILLIC', 30, u'az')
('LANGUAGE_AZERI_LATIN', 31, u'az')
('LANGUAGE_BASHKIR', 32, u'ba')
('LANGUAGE_BASQUE', 33, u'eu_ES')
('LANGUAGE_BELARUSIAN', 34, u'be_BY')
('LANGUAGE_BENGALI', 35, u'bn')
('LANGUAGE_BHUTANI', 36, u'dz')
('LANGUAGE_BIHARI', 37, u'bh')
('LANGUAGE_BISLAMA', 38, u'bi')
('LANGUAGE_BRETON', 40, u'br')
('LANGUAGE_BULGARIAN', 41, u'bg_BG')
('LANGUAGE_BURMESE', 42, u'my')
('LANGUAGE_CAMBODIAN', 43, u'km')
('LANGUAGE_CATALAN', 44, u'ca_ES')
('LANGUAGE_CHINESE', 45, u'zh_TW')
('LANGUAGE_CHINESE_HONGKONG', 48, u'zh_HK')
('LANGUAGE_CHINESE_MACAU', 49, u'zh_MO')
('LANGUAGE_CHINESE_SIMPLIFIED', 46, u'zh_CN')
('LANGUAGE_CHINESE_SINGAPORE', 50, u'zh_SG')
('LANGUAGE_CHINESE_TAIWAN', 51, u'zh_TW')
('LANGUAGE_CHINESE_TRADITIONAL', 47, u'zh_TW')
('LANGUAGE_CORSICAN', 52, u'co')
('LANGUAGE_CROATIAN', 53, u'hr_HR')
('LANGUAGE_CZECH', 54, u'cs_CZ')
('LANGUAGE_DANISH', 55, u'da_DK')
('LANGUAGE_DEFAULT', 0, u'zh_CN')
('LANGUAGE_DUTCH', 56, u'nl_NL')
('LANGUAGE_DUTCH_BELGIAN', 57, u'nl_BE')
('LANGUAGE_ENGLISH', 58, u'en_GB')
('LANGUAGE_ENGLISH_AUSTRALIA', 61, u'en_AU')
('LANGUAGE_ENGLISH_BELIZE', 62, u'en_BZ')
('LANGUAGE_ENGLISH_BOTSWANA', 63, u'en_BW')
('LANGUAGE_ENGLISH_CANADA', 64, u'en_CA')
('LANGUAGE_ENGLISH_CARIBBEAN', 65, u'en_CB')
('LANGUAGE_ENGLISH_DENMARK', 66, u'en_DK')
('LANGUAGE_ENGLISH_EIRE', 67, u'en_IE')
('LANGUAGE_ENGLISH_JAMAICA', 68, u'en_JM')
('LANGUAGE_ENGLISH_NEW_ZEALAND', 69, u'en_NZ')
('LANGUAGE_ENGLISH_PHILIPPINES', 70, u'en_PH')
('LANGUAGE_ENGLISH_SOUTH_AFRICA', 71, u'en_ZA')
('LANGUAGE_ENGLISH_TRINIDAD', 72, u'en_TT')
('LANGUAGE_ENGLISH_UK', 59, u'en_GB')
('LANGUAGE_ENGLISH_US', 60, u'en_US')
('LANGUAGE_ENGLISH_ZIMBABWE', 73, u'en_ZW')
('LANGUAGE_ESPERANTO', 74, u'eo')
('LANGUAGE_ESTONIAN', 75, u'et_EE')
('LANGUAGE_FAEROESE', 76, u'fo_FO')
('LANGUAGE_FARSI', 77, u'fa_IR')
('LANGUAGE_FIJI', 78, u'fj')
('LANGUAGE_FINNISH', 79, u'fi_FI')
('LANGUAGE_FRENCH', 80, u'fr_FR')
('LANGUAGE_FRENCH_BELGIAN', 81, u'fr_BE')
('LANGUAGE_FRENCH_CANADIAN', 82, u'fr_CA')
('LANGUAGE_FRENCH_LUXEMBOURG', 83, u'fr_LU')
('LANGUAGE_FRENCH_MONACO', 84, u'fr_MC')
('LANGUAGE_FRENCH_SWISS', 85, u'fr_CH')
('LANGUAGE_FRISIAN', 86, u'fy')
('LANGUAGE_GALICIAN', 87, u'gl_ES')
('LANGUAGE_GEORGIAN', 88, u'ka_GE')
('LANGUAGE_GERMAN', 89, u'de_DE')
('LANGUAGE_GERMAN_AUSTRIAN', 90, u'de_AT')
('LANGUAGE_GERMAN_BELGIUM', 91, u'de_BE')
('LANGUAGE_GERMAN_LIECHTENSTEIN', 92, u'de_LI')
('LANGUAGE_GERMAN_LUXEMBOURG', 93, u'de_LU')
('LANGUAGE_GERMAN_SWISS', 94, u'de_CH')
('LANGUAGE_GREEK', 95, u'el_GR')
('LANGUAGE_GREENLANDIC', 96, u'kl_GL')
('LANGUAGE_GUARANI', 97, u'gn')
('LANGUAGE_GUJARATI', 98, u'gu')
('LANGUAGE_HAUSA', 99, u'ha')
('LANGUAGE_HEBREW', 100, u'he_IL')
('LANGUAGE_HINDI', 101, u'hi_IN')
('LANGUAGE_HUNGARIAN', 102, u'hu_HU')
('LANGUAGE_ICELANDIC', 103, u'is_IS')
('LANGUAGE_INDONESIAN', 104, u'id_ID')
('LANGUAGE_INTERLINGUA', 105, u'ia')
('LANGUAGE_INTERLINGUE', 106, u'ie')
('LANGUAGE_INUKTITUT', 107, u'iu')
('LANGUAGE_INUPIAK', 108, u'ik')
('LANGUAGE_IRISH', 109, u'ga_IE')
('LANGUAGE_ITALIAN', 110, u'it_IT')
('LANGUAGE_ITALIAN_SWISS', 111, u'it_CH')
('LANGUAGE_JAPANESE', 112, u'ja_JP')
('LANGUAGE_JAVANESE', 113, u'jv')
('LANGUAGE_KANNADA', 114, u'kn')
('LANGUAGE_KASHMIRI', 115, u'ks')
('LANGUAGE_KASHMIRI_INDIA', 116, u'ks_IN')
('LANGUAGE_KAZAKH', 117, u'kk')
('LANGUAGE_KERNEWEK', 118, u'kw_GB')
('LANGUAGE_KINYARWANDA', 119, u'rw')
('LANGUAGE_KIRGHIZ', 120, u'ky')
('LANGUAGE_KIRUNDI', 121, u'rn')
('LANGUAGE_KONKANI', 122, u'')
('LANGUAGE_KOREAN', 123, u'ko_KR')
('LANGUAGE_KURDISH', 124, u'ku_TR')
('LANGUAGE_LAOTHIAN', 125, u'lo')
('LANGUAGE_LATIN', 126, u'la')
('LANGUAGE_LATVIAN', 127, u'lv_LV')
('LANGUAGE_LINGALA', 128, u'ln')
('LANGUAGE_LITHUANIAN', 129, u'lt_LT')
('LANGUAGE_MACEDONIAN', 130, u'mk_MK')
('LANGUAGE_MALAGASY', 131, u'mg')
('LANGUAGE_MALAY', 132, u'ms_MY')
('LANGUAGE_MALAYALAM', 133, u'ml')
('LANGUAGE_MALAY_BRUNEI_DARUSSALAM', 134, u'ms_BN')
('LANGUAGE_MALAY_MALAYSIA', 135, u'ms_MY')
('LANGUAGE_MALTESE', 136, u'mt_MT')
('LANGUAGE_MANIPURI', 137, u'')
('LANGUAGE_MAORI', 138, u'mi')
('LANGUAGE_MARATHI', 139, u'mr_IN')
('LANGUAGE_MOLDAVIAN', 140, u'mo')
('LANGUAGE_MONGOLIAN', 141, u'mn')
('LANGUAGE_NAURU', 142, u'na')
('LANGUAGE_NEPALI', 143, u'ne_NP')
('LANGUAGE_NEPALI_INDIA', 144, u'ne_IN')
('LANGUAGE_NORWEGIAN_BOKMAL', 145, u'nb_NO')
('LANGUAGE_NORWEGIAN_NYNORSK', 146, u'nn_NO')
('LANGUAGE_OCCITAN', 147, u'oc')
('LANGUAGE_ORIYA', 148, u'or')
('LANGUAGE_OROMO', 149, u'om')
('LANGUAGE_PASHTO', 150, u'ps')
('LANGUAGE_POLISH', 151, u'pl_PL')
('LANGUAGE_PORTUGUESE', 152, u'pt_PT')
('LANGUAGE_PORTUGUESE_BRAZILIAN', 153, u'pt_BR')
('LANGUAGE_PUNJABI', 154, u'pa')
('LANGUAGE_QUECHUA', 155, u'qu')
('LANGUAGE_RHAETO_ROMANCE', 156, u'rm')
('LANGUAGE_ROMANIAN', 157, u'ro_RO')
('LANGUAGE_RUSSIAN', 158, u'ru_RU')
('LANGUAGE_RUSSIAN_UKRAINE', 159, u'ru_UA')
('LANGUAGE_SAMI', 160, u'se_NO')
('LANGUAGE_SAMOAN', 161, u'sm')
('LANGUAGE_SANGHO', 162, u'sg')
('LANGUAGE_SANSKRIT', 163, u'sa')
('LANGUAGE_SCOTS_GAELIC', 164, u'gd')
('LANGUAGE_SERBIAN', 165, u'sr_RS')
('LANGUAGE_SERBIAN_CYRILLIC', 166, u'sr_RS')
('LANGUAGE_SERBIAN_LATIN', 167, u'sr_RS@latin')
('LANGUAGE_SERBO_CROATIAN', 168, u'sh')
('LANGUAGE_SESOTHO', 169, u'st')
('LANGUAGE_SETSWANA', 170, u'tn')
('LANGUAGE_SHONA', 171, u'sn')
('LANGUAGE_SINDHI', 172, u'sd')
('LANGUAGE_SINHALESE', 173, u'si')
('LANGUAGE_SISWATI', 174, u'ss')
('LANGUAGE_SLOVAK', 175, u'sk_SK')
('LANGUAGE_SLOVENIAN', 176, u'sl_SI')
('LANGUAGE_SOMALI', 177, u'so')
('LANGUAGE_SPANISH', 178, u'es_ES')
('LANGUAGE_SPANISH_ARGENTINA', 179, u'es_AR')
('LANGUAGE_SPANISH_BOLIVIA', 180, u'es_BO')
('LANGUAGE_SPANISH_CHILE', 181, u'es_CL')
('LANGUAGE_SPANISH_COLOMBIA', 182, u'es_CO')
('LANGUAGE_SPANISH_COSTA_RICA', 183, u'es_CR')
('LANGUAGE_SPANISH_DOMINICAN_REPUBLIC', 184, u'es_DO')
('LANGUAGE_SPANISH_ECUADOR', 185, u'es_EC')
('LANGUAGE_SPANISH_EL_SALVADOR', 186, u'es_SV')
('LANGUAGE_SPANISH_GUATEMALA', 187, u'es_GT')
('LANGUAGE_SPANISH_HONDURAS', 188, u'es_HN')
('LANGUAGE_SPANISH_MEXICAN', 189, u'es_MX')
('LANGUAGE_SPANISH_MODERN', 190, u'es_ES')
('LANGUAGE_SPANISH_NICARAGUA', 191, u'es_NI')
('LANGUAGE_SPANISH_PANAMA', 192, u'es_PA')
('LANGUAGE_SPANISH_PARAGUAY', 193, u'es_PY')
('LANGUAGE_SPANISH_PERU', 194, u'es_PE')
('LANGUAGE_SPANISH_PUERTO_RICO', 195, u'es_PR')
('LANGUAGE_SPANISH_URUGUAY', 196, u'es_UY')
('LANGUAGE_SPANISH_US', 197, u'es_US')
('LANGUAGE_SPANISH_VENEZUELA', 198, u'es_VE')
('LANGUAGE_SUNDANESE', 199, u'su')
('LANGUAGE_SWAHILI', 200, u'sw_KE')
('LANGUAGE_SWEDISH', 201, u'sv_SE')
('LANGUAGE_SWEDISH_FINLAND', 202, u'sv_FI')
('LANGUAGE_TAGALOG', 203, u'tl_PH')
('LANGUAGE_TAJIK', 204, u'tg')
('LANGUAGE_TAMIL', 205, u'ta')
('LANGUAGE_TATAR', 206, u'tt')
('LANGUAGE_TELUGU', 207, u'te')
('LANGUAGE_THAI', 208, u'th_TH')
('LANGUAGE_TIBETAN', 209, u'bo')
('LANGUAGE_TIGRINYA', 210, u'ti')
('LANGUAGE_TONGA', 211, u'to')
('LANGUAGE_TSONGA', 212, u'ts')
('LANGUAGE_TURKISH', 213, u'tr_TR')
('LANGUAGE_TURKMEN', 214, u'tk')
('LANGUAGE_TWI', 215, u'tw')
('LANGUAGE_UIGHUR', 216, u'ug')
('LANGUAGE_UKRAINIAN', 217, u'uk_UA')
('LANGUAGE_URDU', 218, u'ur')
('LANGUAGE_URDU_INDIA', 219, u'ur_IN')
('LANGUAGE_URDU_PAKISTAN', 220, u'ur_PK')
('LANGUAGE_UZBEK', 221, u'uz')
('LANGUAGE_UZBEK_CYRILLIC', 222, u'uz')
('LANGUAGE_UZBEK_LATIN', 223, u'uz')
('LANGUAGE_VALENCIAN', 224, u'ca_ES@valencia')
('LANGUAGE_VIETNAMESE', 225, u'vi_VN')
('LANGUAGE_VOLAPUK', 226, u'vo')
('LANGUAGE_WELSH', 227, u'cy')
('LANGUAGE_WOLOF', 228, u'wo')
('LANGUAGE_XHOSA', 229, u'xh')
('LANGUAGE_YIDDISH', 230, u'yi')
('LANGUAGE_YORUBA', 231, u'yo')
('LANGUAGE_ZHUANG', 232, u'za')
('LANGUAGE_ZULU', 233, u'zu')

3、en子目录下需要有个LC_MESSAGES子目录,这个不能改。

4、LC_MESSAGES目录下存放autoupdate.mo语言文件,对照代码wx.locale().AddCatalog('autoupdate'),文件名字可以修改。

其他

1、以上内容都是自己读代码琢磨以及google出来的,已经使用正常,唯一的问题:

语言文件的目录规则(譬如en与wx.LANGUAGE_ENGLISHT想对应)的具体机制,没看到实现源码(貌似被封装wx的dll里了),若有高手知情,请不吝赐教。

2、另外,i18n的机制不是python的首创,还多语言都有类似的实现,不过mo文件能否通用没试过。

3、脑洞大开,python的开发工具wing,wxpython包等等,是否也支持国际化,有待研究,不过确确实实在安装目录里看到了语言文件目录。

4、与cxfreeze的结合,可能还是会存在文件目录的问题,估计要判断frozen了。

经验证cxfreeze支持wx.locale,没问题,赞 ^_^

5、wxpython3.0.2下有个很强大的例子程序Editra,有关这个Edittra:

首先它本身是一个功能很强大的开源产品,功能有实用性(网上有编译好的版本供下载)。

其次它的源码结构性很好,用了很多wx里不太被人知道,但很强大的机制,譬如pubsub,很值得研究:

a、editra一开始会编译出错,需要修改ed_xml.py文件的import部分。

#import extern.dexml as dexml

#from extern.dexml.fields

import * import dexml as dexml

from dexml.fields import *

把extern.dexml换成dexml,至于dexml哪里来的?当然是用pip install dexml安装了。

b、editra目录下有个ed_i18n.py,这个小程序实现了两个很好的功能:

1)、GetAvailLocales()获取当前目录下已经安装的mo文件。

2)、GetLocaleDict()获取当前已安装的mo文件,对应的wx.LANGUAGE_XXX的值,这个值就是wx.locale()的参数。

c、editra实现了不基于esky的update,个人觉得可以学习。

以上内容,都是个人理解,错误之处请指正。

python下wxpython程序国际化的实践(中文英文切换)的更多相关文章

  1. python下彻底解决浏览器多窗口打开与切换问题

    # coding=utf-8 from selenium import webdriverimport timebrowser=webdriver.Firefox()#browser.maximize ...

  2. python下彻底解决浏览器多标签打开与切换问题

    #coding:utf-8#Right_key_click and Tad switch#by dengpeiyou date:2018-7-7from selenium import webdriv ...

  3. 谷歌浏览器控制台 f12怎么设置成中文/英文 切换方法,一定要看到最后!!!

    1.打开谷歌浏览器 2.右键选择检查或 f12 打开控制台 3.点击控制台右边的设置 4.中切英 选择偏好设置->语言=>English 5.英切中 6.选择中文 7.重启 8.切换中文成 ...

  4. 解决archlinux下QT程序,以及wineQQ无法输入中文(.xinitrc)

    昨天安了i3wm,发现fcitx在很多程序中无法输入中文,nixnote2,还有ss-qt5 查了wiki,明明有在~/.xinitrc中加入 export XMODIFIERS=@im=fcitx ...

  5. 简明python教程 --C++程序员的视角(一):数值类型、字符串、运算符和控制流

    最初的步骤 Python是大小写敏感的 任何在#符号右面的内容都是注释 >>> help('print')在“print”上使用引号,那样Python就可以理解我是希望获取关于“pr ...

  6. 基于Struts2框架实现登录案例 之 程序国际化

    国际化牵涉的知识非常多,这里只能简单的介绍,程序国际化的一般做法是:在jsp页面时, 不是直接输出信息,而是输出一个key值,该key值在不同语言环境下找到对应资源文件下的 对应信息,因此首先要创建满 ...

  7. 使用Python,字标注及最大熵法进行中文分词

    使用Python,字标注及最大熵法进行中文分词 在前面的博文中使用python实现了基于词典及匹配的中文分词,这里介绍另外一种方法, 这种方法基于字标注法,并且基于最大熵法,使用机器学习方法进行训练, ...

  8. Django是Python下的一款网络服务器框架

    被解放的姜戈01 初试天涯   Django是Python下的一款网络服务器框架.Python下有许多款不同的框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django ...

  9. ios应用程序国际化

    1.程序名称国际化: 在Xcode中新建项目后,能够在project的info选项卡中找到Localization的项目,能够加入应用程序须要支持的国际语言. 回到项目中能够发如今InfoPlist. ...

随机推荐

  1. MongoDB的“not master and slaveok=false”错误解决

    在客户端操作MongoDB时经常会如下错误: SECONDARY> show collections; Fri Jul :: uncaught exception: error: { } 原因是 ...

  2. 【Leetcode】292. Nim游戏

    题目链接:https://leetcode-cn.com/problems/nim-game/description/ 您和您的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1  ...

  3. 我进行jvm内存调优的一些记录

    jvm内存调优的一些记录 java内存调优的方法和过程 可以使用 jmap -heap pid号 查看,例如pid是9300,执行的结果可能是这样的. root@ubuntu:~# jmap -hea ...

  4. Go语言封装Http协议GET和POST请求

    本文几乎没有文字叙述: /* 有关Http协议GET和POST请求的封装 */ package net import ( "net/http" "io" &qu ...

  5. C# 利用反射将枚举绑定到下拉框

    前言:反射(Reflection)是.NET提供给开发者的一个强大工具,尽管作为.NET框架的使用者,很多时候不会用到反射.但在一些情况下,尤其是在开发一些基础框架或公共类库时,使用反射会使系统架构更 ...

  6. JS中关于正则的巧妙操作

    var msg="dsada[emoji:37]dsadas[emoji:3900]法拉綏芬河"; function fetch(msg) { var match, result ...

  7. SpringBoot —— AOP注解式拦截与方法规则拦截

    AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. SpringBoot中AOP的使用 ...

  8. HDU5840(SummerTrainingDay08-B 树链剖分+分块)

    This world need more Zhu Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. HDU2157(SummerTrainingDay05-F dp)

    How many ways?? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  10. JavaScript--事件入门(24)

    // JavaScript事件是由访问Web页面的用户引起的一系列操作; // 例如:用户点击;当用户执行某些操作的时候,再去执行一系列代码; 一 事件介绍 // 事件一般是用于浏览器和用户操作进行交 ...