箭头垫示例

理解 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 用户手册

逐行分析

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

class ArrowPad : public QWidget
{
    Q_OBJECT

当运行 lupdate 时,它不仅提取源文本,还将它们分组到上下文中。上下文是在其中出现源文本的类的名称。因此,在这个示例中,“ArrowPad”是一个上下文:它是 ArrowPad 类中的文本的上下文。宏 Q_OBJECTArrowPad 中定义 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;

在《MainWindow》的实现中,《mainwindow.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);

根据当前的区域设置选择要使用的翻译。例如,可以使用设置《LANG》环境变量来影响《QLocale::system()`》。请注意,对于《.qm》消息文件(以及 TS 文件)使用的命名规范,包含了区域设置,使得根据区域设置选择翻译文件变得容易实现。

如果为选定的区域设置没有 QM 消息文件,则将使用原始源文本,且不会引发错误。

翻译成法语和荷兰语

首先将示例应用程序翻译成法语。使用《arrowpad_fr.ts》启动 Qt Linguist。你应该会看到七组源文本("&Up","&Left" 等)分组成两个上下文("ArrowPad" 和 "MainWindow")。

现在,输入以下翻译

  • ArrowPad
    • &Up - &Haut
    • &Left - &Gauche
    • &Right - &Droite
    • &Down - &Bas
  • MainWindow
    • E&xit - &Quitter
    • Ctrl+Q - Ctrl+Q
    • &File - &Fichier

标记为完成并进入下一个源文本的《Done & Next》按钮。在输入每个翻译后,可以使用其快捷键(参见翻译菜单栏)来加快速度。

保存文件,并使用《arrowpad_nl.ts》对荷兰语进行相同的操作。

  • ArrowPad
    • &Up - &Omhoog
    • &Left - &Links
    • &Right - &Rechts
    • &Down - Omlaa&g
  • MainWindow
    • E&xit - &Afsluiten
    • Ctrl+Q - Ctrl+A
    • File - &Bestand

我们需要将《tt1_fr.ts》和《tt1_nl.ts》翻译源文件转换为 QM 文件。我们可以使用与之前一样使用的《Qt Linguist》;然而,使用命令行工具《lrelease》可以确保创建《所有》应用程序的 QM 文件,无需记住从《Qt Linguist》中逐个加载和标记为《File|Release》。

输入

lrelease arrowpad.pro

当使用 CMake 时,输入

cmake --build . --target release_translations

这应该会创建《arrowpad_fr.qm》和《arrowpad_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

© 2024 Qt公司。此处包含的文档贡献版权归属于各自的所有者。所提供的文档 根据GNU自由文档许可协议版本1.3许可,由自由软件基金会发布。Qt及其相应标志是Qt公司在芬兰及/或其他国家/地区注册的商标。所有其他商标均为各自所有者的财产。