QT Application想要支持多语言,需要添加一个项目对应的ts(translation source)文件。每支持一种语言就要添加一个ts文件。同时在cmake中指明翻译文件。

# LinguistTools是多语言组件
find_package(Qt6 CREQUIRED COMPONENTS Widgets LinguistTools)
 
# translation source (ts)
set(TS_FILES src/i18n/QWdigetTutorial_zh_CN.ts)
 
set(PROJECT_SOURCES
        src/main.cpp
        src/mainwindow.cpp
        src/mainwindow.h
        src/mainwindow.ui
        ${TS_FILES}
        textfinder.qrc
)
 
# translation target
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
add_custom_target(translation ALL DEPENDS ${QM_FILES})
qt_add_lrelease(QM_FILES)

同时在代码中调用翻译文件,

// main.cpp
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    // add a translation
    QTranslator translator;
    QLocale locale = QLocale::system(); // get system locale
    qDebug() << "syslocale is " << locale.name();
    // replace your project name here
    // something like "QWidgetTutorial_zh_CN"
    QString basename = "QWdigetTutorial_" + locale.name();
    if (translator.load(basename)) {
        a.installTranslator(&translator);
    }
 
    MainWindow w;
    w.setWindowFlags(Qt::Window | Qt::WindowCloseButtonHint);
    w.show();
    return a.exec();
}

上述代码中直接使用文件名的形式QWidgetTutorial_zh_CN,实际上ts文件会被编译成qm文件使用。上面代码能读到qm文件的条件有二,

  1. 可执行文件必须和翻译文件在一个目录
  2. 执行时必须在可执行文件所在目录执行,即使满足条件1,但我像这样执行src/<executable>,那么src目录下的翻译文件是读不到的。也就是执行目录(并不一定是可执行文件所在的目录)下必须有翻译文件(xx.qm)。

例如,linux命令行很多,随着当前目录的变化,执行/usr/bin/ls,他的执行目录也会变化不是吗。

如何生成ts文件?

先创建ts文件,大部分时候Qt Creator会帮你创建。空文件长这样,

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
</TS>

通过在CMakeLists.txt里面指定

qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
add_custom_target(translation ALL DEPENDS ${QM_FILES})

然后

make translation

即可往ts里面填充待翻译的文本,自动从源文件中提取,标记为“unfinished”表示还没翻译。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
    <name>MainWindow</name>
    <message>
        <location filename="../mainwindow.ui" line="14"/>
        <source>MainWindow</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="32"/>
        <source>Keyword</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="42"/>
        <source>Find</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="65"/>
        <source>file</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="72"/>
        <source>window</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="78"/>
        <source>help</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="89"/>
        <source>open</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="94"/>
        <source>close</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <location filename="../mainwindow.ui" line="99"/>
        <source>about</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>

然后通过Qt Creator自带的linguist工具添加翻译即可。

linguist QWdigetTutorial_zh_CN.ts

翻译完成之后,再make translation一些即可编译出翻译好的QWdigetTutorial_zh_CN.qm文件,程序直接读取他即可达到翻译效果。