index.lxp@lxpwrap=c8212_252ehtm.htm

来自「GUI Programming with Python」· HTM 代码 · 共 634 行

HTM
634
字号
    <table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td>    <div align="center" id="bldcontent">      <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a>      <br>      <div class="symbol">Your OpenSource Publisher&#153;</div>    </div>      </td></tr></table>    <div align="center" class="author">      	<a href="../products.lxp">Products</a>	&nbsp;|&nbsp;	<a href="../wheretobuy.lxp">Where to buy</a>	&nbsp;|&nbsp;	<a href="../bookstore.lxp">Retailers</a>	&nbsp;|&nbsp;	<a href="../faq.lxp">FAQ</a>	&nbsp;|&nbsp;        <a href="../writeforus.lxp">Write for Us.</a>        &nbsp;|&nbsp;        <a href="#contact">Contact Us.</a>  </div>    <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%">      <div class="content">        <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%">          <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div>                    <HTML><HEAD><TITLE>Internationalizing an Application</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Creating real applications with PyQt"HREF="p4627.htm"><LINKREL="PREVIOUS"TITLE="Conclusion"HREF="x8207.htm"><LINKREL="NEXT"TITLE="Delivering your Application"HREF="c8349.htm"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=x8207_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=c8349_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1>Chapter 25. Internationalizing an Application</A></H1><P>For more than a century people have been    uttering the platitude that the world is getting smaller all the    time. That's nonsense: it's getting bigger. Although most computer    users are still able to work with English-only applications, even    speakers of <SPAN><ICLASS="EMPHASIS">really</I></SPAN> obscure languages, like    Limbu, own computers and would like some applications in their own    language.</P><P>An open-source effort like KDE offers    more-or-less complete translations of the entire desktop,    including all applications in dozens of languages. And, for a    consideration, you can get a version of Windows in your own    language, too, even if that language is Basque.</P><P>Of course, there are other aspects to the    internationalization of an application, like date and number    formats, currency, keyboard, preferred dialog layout and so on.    Some of these aspects are handled by Qt - like reversing the    dialog layout if the current script is right-to-left. Others, like    the date and number formats are handled by Python's    <TTCLASS="FILENAME">locale</TT> module - which is alas severely    underdocumented.</P><P>Translating texts on screen can be handled    either by PyQt - using the <TTCLASS="CLASSNAME">QTranslator</TT>    class, or by Python itself - using the    <TTCLASS="FILENAME">gettext</TT> module. PyQt's    <TTCLASS="CLASSNAME">QTranslator</TT> is far more convenient in use,    but <TTCLASS="FILENAME">gettext</TT> is based on the wide-spread GNU    gettext library, which is also used by KDE for its    translations.</P><DIVCLASS="SECT1"><H1CLASS="SECT1">Translating screen texts</A></H1><P>The first task is to surround all      translatable text with the method <TTCLASS="FUNCTION">self.tr()</TT>      - every <TTCLASS="CLASSNAME">QObject</TT> - derived class has that      method. You don't have to do that manually with designs you have      generated with the Designer module or      <SPANCLASS="APPLICATION">Qt燚esigner</SPAN>. However, for Kalam,      it's a fair bit of work - I'll only show a fragment here:</P><PRECLASS="PROGRAMLISTING"># fragment from kalamapp.py ...    def initActions(self):        self.actions = {}        self.actions["fileNew"] = \              QAction(self.tr("New"),                      QIconSet(QPixmap(filenew)),                      self.tr("&#38;New"),                      QAccel.stringToKey(self.tr("CTRL+N",                                                 "File|New"))                      self)        self.connect(self.actions["fileNew"],                     SIGNAL("activated()"),                     self.slotFileNew)        self.actions["fileOpen"] = \              QAction(self.tr("Open"),                      QIconSet(QPixmap(fileopen)),                      self.tr("&#38;Open"),                      QAccel.stringToKey(self.tr("CTRL+O",                                                 "File|Open")),                      self)        self.connect(self.actions["fileOpen"],                     SIGNAL("activated()"),                     self.slotFileOpen) ...    </PRE><P>You must not only mark all text that will      appear on screen, but also all accelerator keys, otherwise      translators won't be able to translate them. The extra argument      to <TTCLASS="FUNCTION">tr()</TT> gives the translator some extra      context.</P><P>The <TTCLASS="FUNCTION">tr()</TT> serves two      purposes: at first, it used as a recognition point for a small      utility that extracts the strings to create message catalogs -      files full of translatable text that you can send your Limbu      speaking friends to translate for you.</P><P>Secondly, when you run the application,      <TTCLASS="FUNCTION">tr()</TT> looks in a message database to find      the right string. This is a very fast operation, so you don't      have to worry about performance loss.</P><P>After you've marked all translatable      strings, you can use a utility to generate translatable message      files. Qt's utility&#8212;either <BCLASS="COMMAND">lupdate</B> or      <BCLASS="COMMAND">findtr</B>&#8212;can only work with strings marked with      <TTCLASS="FUNCTION">tr()</TT>, and only with double-quoted      strings.</P><P>There is a significant, though quite        esoteric, difference between the way Qt2 and Qt3 handle the        <TTCLASS="FUNCTION">tr()</TT>. This means that when you use a        version of PyQt designed to work with Qt 2, the        <TTCLASS="FUNCTION">tr()</TT> doesn't work out of the box. You        need to add a <TTCLASS="FUNCTION">tr()</TT> to all your classes        that calls <TTCLASS="FUNCTION">qApp.translate()</TT>. This is what        is done in the current <SPANCLASS="APPLICATION">Kalam</SPAN> code,        because I wrote and developed the book using PyQt 2.5.</P><P>Another important difference: in Qt 3, you can also use        <TTCLASS="FUNCTION">trUtf8()</TT>, if the source text is in the        utf-8 encoding. That means that if your translators produce        utf-8 encoded files, instead of plain two-byte Unicode text,        you should use this function, instead of        <TTCLASS="FUNCTION">tr()</TT>. With PyQt 3 for Qt 3,        <TTCLASS="FUNCTION">trUtf8*()</TT> will be used automatically by        <BCLASS="COMMAND">pyuic</B>.</P><P>You can also tell      <SPANCLASS="APPLICATION">pyuic</SPAN> to use another function instead      of <TTCLASS="FUNCTION">tr()</TT> - for instance, the Python      pygettext.py default <TTCLASS="FUNCTION">_()</TT>. If you do that,      with the command:</P><PRECLASS="SCREEN">pyuic -tr _ frmsettings.ui       </PRE><P>there will be one important difference: by      default, the translation function <TTCLASS="FUNCTION">tr()</TT> has      class-local scope, i.e. it is prefixed with      <TTCLASS="VARNAME">self</TT>. But a custom translation function has      global scope - exactly what you need for the Python      implementation of gettext.</P><P>So, you can either do:</P><PRECLASS="SCREEN">boud@calcifer:~/doc/pyqt/ch19/kalam &#62; pygettext.py --keyword=tr kalamapp.py    </PRE><P>Which creates a file called      <TTCLASS="FILENAME">messages.pot</TT>, or:</P><PRECLASS="SCREEN">boud@calcifer:~/doc/pyqt/ch19/kalam &#62; findtr kalamapp.py      </PRE><P>The resulting files are almost identical -      except for the minor detail of order. You should make a copy of      these files for every language you need a translation for, and      send them to your translators. They can use any editor, or a      specialised application like <SPANCLASS="APPLICATION">KBabel</SPAN>      to translate the text, and send it back in the form of a      translated <TTCLASS="FILENAME">.pot</TT> file.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>KBabel</P></DIV></P></DIV><P>The result can be compiled to      <TTCLASS="FILENAME">.mo</TT> files using the      <TTCLASS="FILENAME">msgfmt.py</TT> utility which should hide      somewhere in you Python installation.</P><P>Finally, you can use these message catalog      by loading it and installing a global function      <TTCLASS="FUNCTION">_()</TT>. (That should have been the function      you used to mark your strings):</P><PRECLASS="PROGRAMLISTING">import gettextgettext.install('kalam')    </PRE><P>Or for message catalogs in the Unicode      encoding:</P><PRECLASS="PROGRAMLISTING">import gettextgettext.install('kalam', '/usr/share/locale', unicode=1)    </PRE><P>Here, the path should point to a locale directory where all      message files can be found.</P><P>If you are working with Qt 3.0, you can      also use a new tool: <SPANCLASS="APPLICATION">Qt Linguist</SPAN>.      This extracts the messages to a special, xml-based, format, and      you can create message catalogs with a nice GUI frontend.</P><P>To use <SPANCLASS="APPLICATION">Qt        Linguist</SPAN>, you need to make a Qt project file      containing the following text:</P><PRECLASS="SCREEN">SOURCES = configtest.py \dlgfindreplace.py \dlgsettings.py \docmanager.py \docmanagertest.py \edmund.py \frmfindreplace.py \frmsettings.py \kalamapp.py \kalamconfig.py \kalamdoc.py \kalamview.py \macromanager.py \macromanagertest.py \main.py \resources.py \sitecustomize.py \startup.py TRANSLATIONS = kalam_nl.ts    </PRE><P>And run the following command:</P><PRECLASS="SCREEN">boud@calcifer:~/doc/pyqt/ch19/kalam &#62; lupdate kalam.pro    </PRE><P>After spewing out a lot of warnings (this      tool expects C++, not python) a file in xml format is created      which  you can edit with an editor or with      <SPANCLASS="APPLICATION">Qt燣inguist</SPAN>.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>The Qt Linguist screen</P></DIV></P></DIV><P>If the translator is finished, he or she      can choose "release" in the menubar and generate a      <TTCLASS="FILENAME">.qm</TT> message catalog.</P><P>Using this catalog in your application is      a simple matter of installing the appropriate translator:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 25-1. Installing the translator</B></P><PRECLASS="PROGRAMLISTING">#!/usr/bin/env python"""main.py - application startercopyright: (C) 2001, Boudewijn Remptemail:     boud@rempt.xs4all.nl"""import sys, localefrom qt import *from kalamapp import KalamAppfrom kalamdoc import KalamDocfrom kalamview import KalamViewimport kalamconfigfrom resources import TRUE, FALSEdef main(args):    app=QApplication(args)    translator = QTranslator(app)    translator.load("kalam_" + locale.getlocale()[0] + ".qm",                    kalamconfig.get("libdir","."))    app.installTranslator(translator)    kalam = KalamApp()    app.setMainWidget(kalam)    kalam.show()    if len(args) &#62; 1:        for arg in args[1:]:            document=KalamDoc()            document.open(arg)            kalam.docManager.addDocument(document, KalamView)    app.exec_loop()    if __name__=="__main__":    main(sys.argv)    </PRE></DIV><P>Two remarks: note how we use the      <TTCLASS="FILENAME">locale</TT> module to determine the language of      the user. This returns a tuple containing a language code and a      character set that correspond the user locale, as set by the      operating system: <TTCLASS="VARNAME">['en_US', 'ISO8859-1']</TT>. If      you always use the language code as the second part for your      filename, then Qt will be able to determine which translation      file to load.</P><P>Note also that the location of that      message file is determined by a configuration option. Standard      Unix <TTCLASS="FILENAME">.mo</TT> files tend to go into      <TTCLASS="FILENAME">/usr/share/locale/</TT>, but there is no      corresponding standard for Qt <TTCLASS="FILENAME">.qm</TT> messages,      and you might as well put those in the application installation      directory. Where that is, will be determined in the next      chapter.</P></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><A accesskey="P" href="index.lxp@lxpwrap=x8207_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=c8349_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Conclusion</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=p4627_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Delivering your Application</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?