📄 linguist-programmer.leaf
字号:
\chapter ProgrammersSupport for multiple languages is extremely simple in Qtapplications, and adds little overhead to the programmer's workload.Qt minimizes the performance cost of using translations bytranslating the phrases for each window as they are created. In mostapplications the main window is created just once. Dialogs are oftencreated once and then shown and hidden as required. Once the initialtranslation has taken place there is no further runtime overhead forthe translated windows. Only those windows that are created,destroyed and subsequently created will have a translationperformance cost.Creating applications that can switch language at runtime is possiblewith Qt, but requires a certain amount of programmer intervention andwill of course incur some runtime performance cost.\section1 Making the Application Translation AwareProgrammers should make their application look for and load theappropriate translation file and mark user-visible text and Ctrlkeyboard accelerators as targets for translation.Each piece of text that requires translating requires context to helpthe translator identify where in the program the text occurs. In thecase of multiple identical texts that require different translations,the translator also requires some information to disambiguate thesource texts. Marking text for translation will automatically causethe class name to be used as basic context information. In some casesthe programmer may be required to add additional information to helpthe translator.\section2 Creating Translation Files\index .ts Files\index Translation Source FilesTranslation files consist of all the user-visible text and Ctrl keyaccelerators in an application and translations of that text.Translation files are created as follows:\index lupdate\index lrelease\list 1\i Run \l lupdate initially to generate the first set of \c .tstranslation source files with all the user-visible text but notranslations.\i The \c .ts files are given to the translator who adds translationsusing \e {Qt Linguist}. \e {Qt Linguist} takes care of any changedor deleted source text.\i Run \l lupdate to incorporate any new text added to theapplication. \l lupdate synchronizes the user-visible text from theapplication with the translations; it does not destroy any data.\i Steps 2 and 3 are repeated as often as necessary.\i When a release of the application is needed \l lrelease is run toread the \c .ts files and produce the \c .qm files used by theapplication at runtime.\endlist\index .pro Files\index Project Files\index qmake!Project FilesFor \l lupdate to work successfully, it must know which translationfiles to produce. The files are simply listed in the application's \c.pro Qt project file, for example:\quotefile tt2/tt2.pro\skipto TRANSLATIONS\printline TRANSLATIONS\printlineSee the \link lupdate "lupdate" \endlink and \link lrelease"lrelease" \endlink sections.\section2 Loading Translations\quotefile tt1/main.cpp\skipto main(\printline main(\printuntil QApplication\index main()This is how a simple \c main() function of a Qt application begins.\index QTranslator!load()\index load()!QTranslator\index QApplication!installTranslator()\index installTranslator()!QApplication\quotefile tt1/main.cpp\skipto main(\printline main(\printuntil app.installTransFor a translation-aware application a translator object is created, atranslation is loaded and the translator object installed into theapplication.\quotefile tt2/main.cpp\skipto main(\printline main(\printuntil app.installTransIn production applications a more flexible approach, for example,loading translations according to locale, might be more appropriate. Ifthe \c .ts files are all named according to a convention such as\e appname_locale, e.g. \c tt2_fr, \c tt2_de etc, then thecode above will load the current locale's translation at runtime.If there is no translation file for the current locale the applicationwill fall back to using the original source text.\section2 Making the Application Translate User-Visible Strings\index tr()\index QObject!tr()User-visible strings are marked as translation targets by wrapping themin a \c tr() call, for example:\code button = new QPushButton( "&Quit", this );\endcodewould become\code button = new QPushButton( tr("&Quit"), this);\endcode\index Q_OBJECTAll \l QObject subclasses that use the \c Q_OBJECT macro implementthe \c tr() function.Although the \c tr() call is normally made directly since it isusually called as a member function of a \l QObject subclass, inother cases an explicit class name can be supplied, for example:\code QPushButton::tr("&Quit")\endcodeor\code QObject::tr("&Quit")\endcode\section2 Distinguishing Identical Strings That Require DifferentTranslations\index Translation Contexts\index Contexts!for Translation\index lupdateThe \l lupdate program automatically provides a \e context for everysource text. This context is the class name of the class that containsthe \c tr() call. This is sufficient in the vast majority of cases.Sometimes however, the translator will need further information touniquely identify a source text; for example, a dialog that containedtwo separate frames, each of which contained an "Enabled" option wouldneed each identified because in some languages the translation woulddiffer between the two. This is easily achieved using thetwo argument form of the \c tr() call, e.g.\code rbc = new QRadioButton( tr("Enabled", "Color frame"), this );\endcodeand\code rbh = new QRadioButton( tr("Enabled", "Hue frame"), this );\endcode\index Ctrl KeyCtrl key accelerators are also translatable:\quotefile tt3/mainwindow.cpp\skipto quit()\printline quit()\printuntil QuitIt is strongly recommended that the two argument form of \c tr() is usedfor Ctrl key accelerators. The second argument is the only clue thetranslator has as to the function performed by the accelerator.\section2 Helping The Translator With Navigation Information\index TRANSLATOR!in Comments\index Translator Comments\index Comments!for TranslatorsIn large complex applications it may be difficult for the translator tosee where a particular source text comes from. This problem can besolved by adding a comment using the keyword \e TRANSLATOR whichdescribes the navigation steps to reach the text in question; e.g.\code /* TRANSLATOR FindDialog Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog. */\endcodeThese comments are particularly useful for widget classes.\section2 Coping With C++ Namespaces\index Namespaces\index C++!Namespaces\index lupdateC++ namespaces and the \c {using namespace} statement can confuse\l lupdate. It will interpret \c MyClass::tr() as meaning justthat, not as \c MyNamespace::MyClass::tr(), even if \c MyClass isdefined in the \c MyNamespace namespace. Runtime translation ofthese strings will fail because of that.\index TRANSLATOR!in Comments\index Translator Comments\index Comments!for TranslatorsYou can work around this limitation by putting a \e TRANSLATORcomment at the beginning of the source files that use \cMyClass::tr():\code /* TRANSLATOR MyNamespace::MyClass */\endcodeAfter the comment, all references to \c MyClass::tr() will beunderstood as meaning \c MyNamespace::MyClass::tr().\section2 Translating Text that is Outside of a QObject subclass\section3 Using QApplication::translate()If the quoted text is not in a member function of a QObject subclass,use either the tr() function of an appropriate class, or theQApplication::translate() function directly: \code void some_global_function( LoginWidget *logwid ) { QLabel *label = new QLabel( LoginWidget::tr("Password:"), logwid ); } void same_global_function( LoginWidget *logwid ) { QLabel *label = new QLabel( qApp->translate("LoginWidget", "Password:"), logwid ); }\endcode\section3 Using QT_TR_NOOP() and QT_TRANSLATE_NOOP()If you need to have translatable text completely outside a function,there are two macros to help: QT_TR_NOOP() and QT_TRANSLATE_NOOP().These macros merely mark the text for extraction by \l{lupdate}.The macros expand to just the text (without the context). Example of QT_TR_NOOP(): \code QString FriendlyConversation::greeting( int greet_type ) { static const char* greeting_strings[] = { QT_TR_NOOP( "Hello" ), QT_TR_NOOP( "Goodbye" ) }; return tr( greeting_strings[greet_type] ); }\endcodeExample of QT_TRANSLATE_NOOP(): \code static const char* greeting_strings[] = { QT_TRANSLATE_NOOP( "FriendlyConversation", "Hello" ), QT_TRANSLATE_NOOP( "FriendlyConversation", "Goodbye" ) }; QString FriendlyConversation::greeting( int greet_type ) { return tr( greeting_strings[greet_type] ); } QString global_greeting( int greet_type ) { return qApp->translate( "FriendlyConversation", greeting_strings[greet_type] ); }\endcode\section1 TutorialsThree tutorials are presented. The first demonstrates the creation ofa \l QTranslator object. It also shows the simplest use of the \ctr() function to mark user-visible source text for translation. Thesecond tutorial explains how to make the application load thetranslation file applicable to the current locale. It also shows theuse of the two-argument form of \c tr() which provides additionalinformation to the translator. The third tutorial explains howidentical source texts can be distinguished even when they occur inthe same context. This tutorial also discusses how the translationtools help minimize the translator's work when an application isupgraded.\section2 Tutorial 1: Loading and Using Translations\img tt1_en.png\caption Tutorial 1 Screenshot, English version\include tt1/tt1.pro\caption \c tt1.pro\include tt1/main.cpp\caption \c main.cppThis example is a reworking of the \link tutorial1-01.html"hello-world" \endlink example from \link tutorial.html Tutorial#1\endlink, with a Latin translation. The \e {Tutorial 1 Screenshot,English version}, above, shows the English version.\quotefile tt1/main.cpp\section3 Line by Line Walk-through\quotefile tt1/main.cpp\skipto qtranslator\printline qtranslator\index QTranslatorThis line includes the definition of the \l QTranslator class. Objects of this class provide translations for user-visible text.\skipto QTranslator\printuntil torCreates a \l QTranslator object without a parent.\printline load\index tt1_la.qmTries to load a file called \c tt1_la.qm (the \c .qm file extension isimplicit) that contains Latin translations for the source texts used inthe program. No error will occur if the file is not found.\index QApplication!installTranslator()\index installTranslator()!QApplication\printline installTranslatorAdds the translations from \c tt1_la.qm to the pool of translations usedby the program.\index Hello World\printline helloCreates a push button that displays "Hello world!". If \c tt1_la.qmwas found and contains a translation for "Hello world!", thetranslation appears; if not, the source text appears.\index tr()\index QObject!tr()All classes that inherit \l QObject have a \c tr() function. Insidea member function of a \l QObject class, we simply write \c tr("Helloworld!") instead of \c QPushButton::tr("Hello world!") or \cQObject::tr("Hello world!").\section3 Running the Application in English\index English Language
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -