箭头垫示例

了解Qt Linguist 上下文概念和使用两种或多种语言。

我们将使用法语和荷兰语这两种翻译,尽管对一个应用程序可能使用的翻译数量没有有效限制。

使用 qmake 时,arrowpad.pro 中的相关行是:

HEADERS      = arrowpad.h \
               mainwindow.h
SOURCES      = arrowpad.cpp \
               main.cpp \
               mainwindow.cpp

TRANSLATIONS = arrowpad_fr.ts \
               arrowpad_nl.ts

使用 CMake 时,CMakeLists.txt 中的相关行是

find_package(Qt6 REQUIRED COMPONENTS LinguistTools)

qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES fr nl)

qt6_add_translations(arrowpad
    QM_FILES_OUTPUT_VARIABLE qm_files)
install(FILES ${qm_files} DESTINATION ${INSTALL_EXAMPLEDIR})

运行lupdate 。它将生成两个相同的信息文件arrowpad_fr.tsarrowpad_nl.ts 。这些文件将包含所有标有tr() 调用及其上下文的翻译源文本。

使用 qmake 时,必须手动运行lupdate

lupdate arrowpad.pro

使用 CMake 时,请构建update_translations 目标以运行lupdate

cmake --build . --target update_translations

有关翻译 Qt 应用程序的更多信息,请参阅Qt Linguist Manual

逐行演练

arrowpad.h 中,我们定义了ArrowPad 子类,它是 QWidget 的子类。在上面的截图中,带有四个按钮的中心部件是ArrowPad

class ArrowPad : public QWidget
{
    Q_OBJECT

运行lupdate 时,它不仅会提取源文本,还会将它们归类到上下文中。上下文是源文本所在类的名称。因此,在本例中,"ArrowPad "就是一个上下文:它是ArrowPad 类中文本的上下文。Q_OBJECT 宏在ArrowPad 中这样定义tr(x)

qApp->translate("ArrowPad", x)

知道每个源文本出现在哪个类中,就能 Qt Linguist将逻辑上相关的文本分组,例如,一个对话框中的所有文本将具有该对话框类名的上下文,并将一起显示。这为译员提供了有用的信息,因为文本出现的上下文可能会影响其翻译方式。对于某些翻译,键盘加速器可能需要更改,而将特定上下文(类)中的所有源文本组合在一起,可以使译员更容易执行任何加速器更改,而不会产生冲突。

arrowpad.cpp 中,我们实现了ArrowPad 类。

    upButton = new QPushButton(tr("&Up"));
    downButton = new QPushButton(tr("&Down"));
    leftButton = new QPushButton(tr("&Left"));
    rightButton = new QPushButton(tr("&Right"));

我们为每个按钮的标签调用ArrowPad::tr() ,因为标签是用户可见的文本。

class MainWindow : public QMainWindow
{
    Q_OBJECT

在上面的截图中,整个窗口是一个MainWindow 。这是在mainwindow.h 头文件中定义的。在这里,我们也使用Q_OBJECT ,这样MainWindow 将成为 Qt Linguist.

    arrowPad = new ArrowPad;

MainWindowmainwindow.cpp 的实现中,我们创建了ArrowPad 类的实例。

    exitAct = new QAction(tr("E&xit"), this);
    exitAct->setShortcut(QKeySequence(tr("Ctrl+Q", "Quit")));
    connect(exitAct, &QAction::triggered, this, &MainWindow::close);

我们还调用了两次MainWindow::tr() ,一次用于操作,一次用于快捷方式。

请注意,tr() 支持其他语言的不同按键。在英语中,"Ctrl+Q "是 "退出 "的最佳选择,但荷兰语翻译者可能希望使用 "Ctrl+A"(表示 Afsluiten),德语翻译者则希望使用 "Strg+E"(表示 Beenden)。当tr() 用于Ctrl 按键加速器时,应使用双参数形式,第二个参数描述加速器执行的功能。

我们的main() 函数照例定义在main.cpp 中。

    QTranslator translator;
    if (translator.load(locale, u"arrowpad"_s, u"_"_s))
        app.installTranslator(&translator);

我们根据当前的本地语言选择使用哪种翻译。QLocale::system(例如,可以通过设置LANG 环境变量来影响()。请注意,使用包含.qm 消息文件(和 TS 文件)语言的命名约定,可以轻松实现根据语言选择翻译文件。

如果所选语言没有 QM 信息文件,则将使用原始源文本,不会出现错误。

翻译成法语和荷兰语

我们首先将示例应用程序翻译成法语。从 Qt Linguist使用arrowpad_fr.ts 。您将看到七个源文本("&Up"(向上)、"&Left"(向左)等)被归类到两个上下文("ArrowPad"(箭头板)和 "MainWindow"(主窗口))中。

现在,输入以下翻译:

  • ArrowPad
    • &Up - &Haut
    • &Left - &Gauche
    • &Right - &Droite
  • MainWindow
    • E&xit - &Quitter
    • Ctrl+Q - 按 Ctrl+Q
    • 文件 - 文件

Done & Next 按钮标记翻译完成,并转到下一个源文本。在输入每个译文后使用快捷键(见翻译菜单栏)会更快。

保存文件,并通过arrowpad_nl.ts 对荷兰语进行同样的操作:

  • ArrowPad
    • 左 - 链接
    • 向右 - &Rechts
    • 向下 - Omlaa&g
  • MainWindow
    • 退出 - 关闭
    • Ctrl+Q - Ctrl+A
    • 文件 - 标准

我们必须将tt1_fr.tstt1_nl.ts 翻译源文件转换为 QM 文件。我们可以使用 Qt LinguistFile|Release 但是,使用命令行工具lrelease 可以确保创建应用程序的所有QM 文件,而不必记住从 Qt Linguist.

键入

lrelease arrowpad.pro

使用 CMake 时,键入

cmake --build . --target release_translations

这将同时创建arrowpad_fr.qmarrowpad_nl.qm

要使用arrowpad_fr.qm ,请将系统语言改为法语。在 Unix 系统中,以下两个命令之一就可以了:

export LANG=fr
setenv LANG fr

在 Windows 或 Mac 中,将显示语言设置为法语。

运行程序时,您将看到法语版本:

用荷兰语尝试同样的方法(在 Unix 中使用LANG=nl )。现在应该会出现荷兰语版本:

练习

Qt Linguist中的一个翻译标记为未完成,即取消选中 "已完成 "复选框;运行lupdate ,然后运行lrelease ,然后运行示例。这一更改有什么影响?

设置LANG=fr_CA (法文加拿大)并再次运行示例程序。解释为什么结果与LANG=fr 相同。

更改荷兰语翻译中的一个加速器,以消除&Bestand&Boven 之间的冲突。

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.