当前位置: 首页 > news >正文

QT-多语言系统功能开发保姆级教程

目录

【相关链接】

Qt 实现中英文语言切换的示例

1、架构流程和代码示例

①. 项目结构

②. 项目文件(.pro)

③. 窗口头文件(mainwindow.h)

④. 窗口实现文件(mainwindow.cpp)

⑤. 主函数(main.cpp)

⑥. 生成翻译文件(.ts 和 .qm)

2、相关概念和常用操作

①tr()和Qt_TR_NOOP宏

1. tr() 函数

2. QT_TR_NOOP() 宏

②重写changeEvent函数和触发UI刷新retranslateUi函数

③qApp->translate的使用

QT提取和生成多语言库

方式1:使用QT的qtcreator图形界面提取和生成语言库

方式2:使用指令提取和生成语言库

Qt 的富文本(Rich Text)和HTML 标签

1. 文本样式

2. 字体与颜色

3. 段落与布局

4. 标题与列表

5. 链接与图片

6. 表格

7. 常用 CSS 样式(部分支持)

8. 应用示例

总结


【相关链接】

QT的QSettings 和 JSON 管理配置文件

Qt 实现中英文语言切换的示例

示例说明:本示例举例实现中英文切换,使用tr()或QT_TR_NOOP对翻译文本进行标记,使用QT语言家进行多语言翻译生成.ts文件,然后生成.qm语言库;同时使用QSetting机制对当前切换语言进行保存,起掉电保存效果,当重启后,会先加载QSetting记录的语言进行加载语言。

1、架构流程和代码示例

①. 项目结构

LanguageSwitchDemo/ ├── LanguageSwitchDemo.pro ├── resources.qrc (可选) ├── main.cpp ├── mainwindow.h ├── mainwindow.cpp ├── translations/ │ ├── en.ts │ ├── zh.ts │ └── generate_qm.sh (可选)

②. 项目文件(.pro)

QT += core widgets SOURCES += main.cpp mainwindow.cpp HEADERS += mainwindow.h # 翻译文件路径 TRANSLATIONS += translations/en_US.ts\ += translations/zh_CN.ts # 指定生成 qm 文件的目标目录(生成的 qm 文件会放在 debug/release 目录下) #CONFIG += lrelease #CONFIG += embed_translations RESOURCES += resources.qrc

③. 窗口头文件(mainwindow.h)

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QWidget> #include <QTranslator> #include <QTimer> #include <QSettings> class QLabel; class QPushButton; class QLineEdit; class QVBoxLayout; class MainWindow : public QWidget { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); protected: void changeEvent(QEvent *event) override; // 监听语言切换事件 private slots: void onLanguageSwitchClicked(); // 切换语言按钮响应 void updateDynamicText(); // 更新动态内容(当前时间) private: typedef enum { LANGUAGE_TYPE_ZH_CN = 0x00, // 简体中文 LANGUAGE_TYPE_EN_US = 0x01, // 英语 } E_LanguageType; void initUI(); // 初始化界面 void retranslateUi(); // 手动刷新所有控件的文本 void ActLang_ZH_CN_Triggered(void); // 切换中文 void ActLang_EN_US_Triggered(void); // 切换英文 QString ReadTranslatorSetting(void); // 获取语言配置 void LoadPreviouTranslator(void); // 加载最近切换的语言 void LanguageSwitch(E_LanguageType language); private: // "MyCompany", "MyApp" 参数配置路径: /root/.config/demo-ui/demo-app.conf #define DEMO_UI_COMPANY "demo-ui" #define DEMO_UI_APP "demo-app" QTranslator m_translator; // 当前使用的翻译器 bool m_isChinese; // 当前是否为中文 // UI 控件 QLabel *m_labelFixed; // 固定文本示例 QLabel *m_labelDynamicDesc; // 动态文本描述(需要翻译) QLabel *m_labelTime; // 时间显示(内容不需翻译) QLineEdit *m_lineEdit; // 输入框(用户动态输入,不翻译) QPushButton *m_switchBtn; // 切换语言按钮 QTimer *m_timer; // 定时更新时间 }; #endif // MAINWINDOW_H

④. 窗口实现文件(mainwindow.cpp)

#include "mainwindow.h" #include <QLabel> #include <QPushButton> #include <QLineEdit> #include <QVBoxLayout> #include <QHBoxLayout> #include <QApplication> #include <QDebug> #include <QDateTime> #include <QCoreApplication> MainWindow::MainWindow(QWidget *parent) : QWidget(parent) , m_isChinese(false) { initUI(); retranslateUi(); // 初始文本(默认英文) updateDynamicText(); // 初始动态时间 // 每秒更新时间 m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, &MainWindow::updateDynamicText); m_timer->start(1000); // 加载上次配置的语言,也可以放到main函数中去 LoadPreviouTranslator(); } MainWindow::~MainWindow() { } void MainWindow::initUI() { // 创建控件 m_labelFixed = new QLabel(this); m_labelDynamicDesc = new QLabel(this); m_labelTime = new QLabel(this); m_lineEdit = new QLineEdit(this); m_switchBtn = new QPushButton(this); // 设置输入框占位文本(在 retranslateUi 中也会翻译) m_lineEdit->setPlaceholderText(tr("Please enter something...")); // 布局 QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_labelFixed); mainLayout->addWidget(m_labelDynamicDesc); mainLayout->addWidget(m_labelTime); mainLayout->addWidget(m_lineEdit); mainLayout->addWidget(m_switchBtn); setLayout(mainLayout); setWindowTitle(tr("Language Switch")); // Language Switch Demo // 连接按钮信号 connect(m_switchBtn, &QPushButton::clicked, this, &MainWindow::onLanguageSwitchClicked); } void MainWindow::retranslateUi() { // 所有需要随语言变化的文本都从这里设置 m_labelFixed->setText(tr("This is a static text.")); m_labelDynamicDesc->setText(tr("Current time:")); m_switchBtn->setText(tr("Switch to Chinese")); setWindowTitle(tr("Language Switch")); m_lineEdit->setPlaceholderText(tr("Please enter something...")); } void MainWindow::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { // 当 QTranslator 变化时,Qt 会自动发送 LanguageChange 事件 retranslateUi(); } QWidget::changeEvent(event); } void MainWindow::ActLang_ZH_CN_Triggered(void) { // 卸载当前翻译 qApp->removeTranslator(&m_translator); // 加载新翻译文件 if (m_translator.load(":/translations/zh_CN.qm")) { qApp->installTranslator(&m_translator); } else { return; } // ui->retranslateUi(this); QSettings settings(DEMO_UI_COMPANY, DEMO_UI_APP); settings.setValue("Setting/SystemSetting/Language", "zh_CN"); } void MainWindow::ActLang_EN_US_Triggered(void) { // 卸载当前翻译 qApp->removeTranslator(&m_translator); // 加载新翻译文件 if (m_translator.load(":/translations/en_US.qm")) { qApp->installTranslator(&m_translator); } else { return; } // ui->retranslateUi(this); QSettings settings(DEMO_UI_COMPANY, DEMO_UI_APP); settings.setValue("Setting/SystemSetting/Language", "en_US"); } //用于从注册表里读取上次设置的界面语言版本 QString MainWindow::ReadTranslatorSetting(void) { QString organization = DEMO_UI_COMPANY; QString appName = DEMO_UI_APP; QSettings settings(organization, appName); QString language = settings.value("Setting/SystemSetting/Language", "zh_CN").toString(); return language; } void MainWindow::LoadPreviouTranslator(void) { QString curLang = ReadTranslatorSetting(); if(curLang == "en_US") { ActLang_EN_US_Triggered(); m_isChinese = false; } else { ActLang_ZH_CN_Triggered(); m_isChinese = true; } } void MainWindow::LanguageSwitch(E_LanguageType language) { switch (language) { case LANGUAGE_TYPE_ZH_CN: ActLang_ZH_CN_Triggered(); break; case LANGUAGE_TYPE_EN_US: ActLang_EN_US_Triggered(); break; default: break; } } void MainWindow::onLanguageSwitchClicked() { m_isChinese = !m_isChinese; E_LanguageType Language = LANGUAGE_TYPE_ZH_CN; if (!m_isChinese) { Language = LANGUAGE_TYPE_EN_US; } LanguageSwitch(Language); // 注意:安装翻译器后,所有使用 tr() 的地方会自动收到 LanguageChange 事件, // 从而重新调用 retranslateUi(),我们只需手动更新动态非 tr() 内容即可 updateDynamicText(); // 更新时间描述(因为描述也是 tr(),但时间数字不需翻译,只需保持显示) } void MainWindow::updateDynamicText() { // 动态内容:当前时间(不需要翻译,直接显示) QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); m_labelTime->setText(currentTime); // 注意:动态文本的描述部分(m_labelDynamicDesc)已在 retranslateUi 中通过 tr() 更新 // 这里只负责刷新时间值本身 }

⑤. 主函数(main.cpp)

#include "mainwindow.h" #include <QApplication> #include <QTranslator> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 加载默认英文翻译(可选,这里先不加载,让界面显示源码中的英文) // 若需要默认中文,可以加载 zh.qm MainWindow w; w.show(); return app.exec(); }

⑥. 生成翻译文件(.ts 和 .qm)

见后续章节:QT提取和生成多语言库,生成en_US.qmzh_CN.qm

加载库文件有两种方式:

情况A:你想使用资源系统(推荐

将 .qm 文件加入资源文件(可选,使用资源系统,打包进二进制可执行文件)【推荐】

创建resources.qrc

<RCC> <qresource prefix="/"> <file>translations/en_US.qm</file> <file>translations/zh_CN.qm</file> </qresource> </RCC>

并在.pro中添加:

RESOURCES += resources.qrc

然后在代码中使用:/translations/xxx.qm加载。

m_translator.load(":/translations/zh_CN.qm"); // 相对路径

这样资源文件会被编译进二进制。

情况B:使用外部文件(不打包进exe)

zh.qmen.qm放到与可执行文件同一目录translations子文件夹下,代码改为:

m_translator.load("translations/zh_CN.qm"); // 相对路径
if (m_translator.load("translations/zh.qm")) { qApp->installTranslator(&m_translator); } else { qDebug() << "Failed to load Chinese translation from translations/zh.qm"; }

情况A和情况B可在加载文件前对文件进行检查:

QString path = ":/translations/zh_CN.qm"; // 或 "translations/zh_CN.qm" if (QFile::exists(path)) { qDebug() << "File exists:" << path; } else { qDebug() << "File NOT found:" << path; }

2、相关概念和常用操作

①tr()和Qt_TR_NOOP宏

在 Qt 的国际化(i18n)框架中,tr()QT_TR_NOOP(或Q_TR_NOOP)都是用于处理可翻译字符串的工具,但用途和行为不同。

注意:只有需要翻译时才需要使用tr()或QT_TR_NOOP,否则不要使用,因为tr()和QT_TR_NOOP需要消耗资源。

1.tr()函数

tr()QObject及其子类提供的一个静态成员函数(实际是静态的tr(),也常被实例方法调用)。它的作用是在运行时将字符串从源代码中的原始语言翻译为目标语言

基本用法

#include <QObject> class MyWidget : public QWidget { Q_OBJECT public: void setLabel() { // "Hello" 会被 `lupdate` 工具提取到 .ts 翻译文件中 // 在运行时根据当前 locale 返回翻译后的文本 ui->label->setText(tr("Hello")); } };

工作原理

  1. 静态提取lupdate扫描源代码,将tr("...")中的字符串提取到.ts文件(XML 格式)。

  2. 翻译:使用 Qt Linguist 工具为每种语言填写翻译。

  3. 运行时加载QTranslator加载对应语言的.qm二进制文件,tr()根据当前 locale 查找并返回翻译后的字符串。

  4. 上下文tr()默认以类名作为翻译上下文(如MyWidget),避免不同类中相同原文的翻译冲突。

重要特点

  • 动态翻译:如果应用程序在运行时改变了 locale(例如用户切换语言),需要重新调用tr()才能获得新翻译。

  • 支持占位符tr("Copy %1 to %2").arg(src).arg(dest)

  • 只能用于QObject子类(或使用QCoreApplication::translate()替代)。

2.QT_TR_NOOP()

QT_TR_NOOP(历史上也有QT_TRANSLATE_NOOP)是一个空操作宏,它的作用是标记字符串为“需要翻译”,但不立即调用翻译函数。常用于需要在静态存储或非QObject子类中保持可翻译字符串的场景。

基本用法

依赖 QObject‌:只有继承自 QObject 的类才能直接使用 tr()。如果在非 QObject 类或全局函数中使用,需使用 QCoreApplication::translate() 或 QObject::tr()

// 全局数组,需要被翻译 static const char* const errorMessages[] = { QT_TR_NOOP("No error"), QT_TR_NOOP("Disk full"), QT_TR_NOOP("Permission denied") }; void showError(int code) { // 真正翻译时使用 qApp->translate() 或 tr() // 注意:这里 tr() 必须在某个 QObject 子类中被调用,以获取正确的上下文 QString msg = tr(errorMessages[code]); // 或者 QCoreApplication::translate("MyContext", errorMessages[code]) }

为什么需要QT_TR_NOOP

  • 如果不加QT_TR_NOOPlupdate无法提取全局或静态字符串,因为它们没有出现在tr()调用中。

  • 但若直接写tr("No error")在全局作用域,tr()需要QObject实例,无法编译。

  • 所以先用宏“标记”该字符串,让lupdate提取它,然后在真正需要翻译的地方(如函数内)再用tr()translate()进行运行时翻译。

变体宏

  • QT_TR_NOOP(context, text):允许显式指定翻译上下文。

  • QT_TRANSLATE_NOOP(context, text):与QT_TR_NOOP类似,但要求上下文和文本两个参数(已弃用,推荐用QT_TR_NOOP配合tr()的上下文)。

②重写changeEvent函数和触发UI刷新retranslateUi函数

QT中UI的文本如果没有变化就不会触发UI刷新(setText可触发文本刷新),导致当切换语言时,也不会去刷新UI文本,达不到语言切换的效果,因此就需要我们重写changeEvent函数和触发UI刷新retranslateUi函数,当m_translator.load qApp->installTranslator 切换语言时,就会触发changeEvent槽函数;如果有多个类且此类中需要翻译,则有需要翻译文本的类都要重写changeEvent函数和实现retranslateUi函数。

注:如果使用的是qtcreator的UI界面拖拽图标生成的代码,则不需要重写changeEvent函数和实现retranslateUi函数,直接在切换语言触发的槽函数中添加ui->retranslateUi(this); 即可在触发语言切换时,自动触发UI刷新。

ui->retranslateUi(this);
// 头文件.h中 // 翻译头文件 #include <QTranslator> class xxxClass: public QWidget { Q_OBJECT public: explicit xxxClass(QWidget *parent = nullptr, const char *context = nullptr); // context是可选项 记录是哪个new此xxxClass,用于后续qApp->translate翻译,context不是必须项,只有当传输动态变化的内容时,才需要此项,如果xxxClass中需要翻译的项都是固定文本,则无需此项 构造函数写成:explicit xxxClass(QWidget *parent = nullptr)即可 void SetText(const QString &alarmText); ... // 1. 重定义 changeEvent 函数 protected: void changeEvent(QEvent *event) override; // 2. 自定义UI刷新函数RetranslateUi private: void RetranslateUi(); ... private: const char *m_context = nullptr; // 记录 xxxClass 的上文context QString m_sourceAlarmStr; // 记录原文本,用于RetranslateUi中翻译 }
// 具体实现.cpp中 xxxClass::xxxClass(QWidget *parent, const char *context) : QWidget(parent), m_context(context) { ... } void xxxClass::SetText(const QString &alarmText) { m_sourceAlarmStr = alarmText; // 记录文本,用于RetranslateUi中去翻译 ... } // 刷新需要文本变化的UI void xxxClass::RetranslateUi(void) { // 实现刷新需要刷新的UI // 如 m_context即记录上下文,指明需要翻译的是哪个上文的内容,适用于有过个上文class调用的场景 QString newText = qApp->translate(m_context, m_sourceAlarmStr.toUtf8().data()); m_xxxText01->SetText(newText); // 如果已知只有一个上文xxxContextClase调用,则直接填上文调用类的类名xxxContextClase即可 newText = qApp->translate("xxxContextClase", m_sourceAlarmStr.toUtf8().data()); m_xxxText02->SetText(newText); // 适用于文本UI内容固定的场景,如文本内容一直为: "Alarm" m_xxxText03->setText(tr("Alarm")); } // 重定义changeEvent函数,捕捉LanguageChange语言切换事件,调用RetranslateUi刷新UI文本 void xxxClass::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { RetranslateUi(); } QWidget::changeEvent(event); }
// 调用示例 void xxxContextClase::xxx_fun(void) { // metaObject()->className()会将自身的类名 "xxxContextClase"传给xxxClass的context,用于其后续的UI刷新指向上下文 xxxClass *xxxDemo= new xxxClass(this, metaObject()->className()); ... }

③qApp->translate的使用

函数原型:

[virtual] QString QTranslator::translate(const char *context, const char *sourceText, const char *disambiguation = nullptr, int n = -1) const Returns the translation for the key (context, sourceText, disambiguation). If none is found, also tries (context, sourceText, ""). If that still fails, returns a null string. Note: Incomplete translations may result in unexpected behavior: If no translation for (context, sourceText, "") is provided, the method might in this case actually return a translation for a different disambiguation. If n is not -1, it is used to choose an appropriate form for the translation (e.g. "%n file found" vs. "%n files found"). If you need to programatically insert translations into a QTranslator, this function can be reimplemented. See also load().

如:我们定义了一个弹窗基础类,主要功能是提示和选择,主要本文显示有:①主题,②内容,③确定和取消按钮。类似如下:

xxxxxx主题 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx提示 取消 确定

这样当有多个父类调用此子类时,都可以根据传入的context来记录父类,对文本进行翻译(见见示例②重写changeEvent函数)。

QT提取和生成多语言库

QT中提取和生成语言库,和在Windows系统还是linux系统上提取和生成语言库无关,是纯粹的文本提取和生成语言库,不过要注意翻译的时候根据需要选择的是32位还是64位。

两种方式都是将源码中的 tr() 或 QT_TR_NOOP宏包含的需要翻译的文本提取出来生成.ts翻译文本,对.ts文文本进行翻译完成后,生成.qm语言库。

方式1:使用QT的qtcreator图形界面提取和生成语言库

步骤1:运行qtcreator,加载工程文件

如安装在ubuntu中的QT5.12.9版本

运行qtcreator

sudo /opt/Qt5.12.9/Tools/QtCreator/bin/qtcreator

或者直接打开windowns上的qtcreator。

步骤2:更新翻译

QT-creator界面【工具】->【外部】->【Qt语言家】->【更新翻译】和 【发布翻译】

更新翻译:会在.pro文件中指定的TRANSLATIONS参数下生成对应的语言.ts文件(如果已经存在,则会更新对应的语言.ts文件)如下:会在translations目录下生成或更新en_US.ts 和zh_CN.ts文件(只以中英文两种语言为例,如果需要再生成其他语言库,同理,直接添加即可,如再添加日语:则添加 translations/ja-JP.ts)

世界语言代码:

Language Code Table

# 翻译文件路径 TRANSLATIONS += translations/en_US.ts translations/zh_CN.ts

发布翻译:会将.ts文件翻译生成对应的语言库.qm文件

更新翻译后,提示如下,更新完成

translations目录下生成.ts文件

步骤3:直接修改ts文件或运行linguist进行多语言翻译

翻译可以选择直接在编辑器上修改ts文件和运行linguist上翻译两种方式。

①直接修改ts文件:ts文件实际上是一个xml文件,直接可以用文本编辑器打开,进行翻译。

如下以zh_CN.ts为例,

<source>和</source>之间:是源码中 tr()或QT_TR_NOOP()包含的部分,如源码中的tr("Please enter something...");

<translation type="unfinished"></translation>:是需要翻译成什么语言,直接替换"unfinished"即可,如翻译成中文:上述的type="unfinished"替换成:请输入...;如:<translation>请输入...</translation>

②使用linguist翻译

如下,根据最终app程序是64位还是32位,选择对应的位数,如app是在64位的linux系统中运行,选择64位linguist进行翻译。

文件-->打开文件

选择对应的.ts文件,如下,两个都选

配置目标语言

en_US:语言:English;国家/地区:可选任意国家或对应的国家,对最终翻译和使用无影响

zh_CN.ts:语言:Chinese,国家/地区:中国

翻译后,左键点击?图标,即可对翻译文本进行标记翻译完成。

图标含义

图标含义

未翻译

已翻译,未标记完成

已翻译,且已标记完成

已翻译,未标记完成,且译文和源文不匹配,只做提示,不影响翻译,如源文有句号等,译文没有。

翻译后的.ts文件如下:以zh_CN.ts为例

全部翻译后,点击保存,然后【文件】->【发布全部】:即可在translations目录下生成.qm语言库文件。

生成.qm语言库

至此,翻译和生成语言库结束。

运行效果:点击切换语言按钮,切换到对应语言

中文:

英文:

以下为翻译常见问题补充:

m_alarmText->setText(tr("Move device in \"∞\" pattern to calibrate."));

源码中的"\"是为了转义字符,但是在翻译中,就直接不用翻译转义字符,因为翻译后的是以字符串的形式保存,即翻译是什么样,显示即是什么样所以翻译直接如下即可:

再比如,

m_alarmText->setText(tr("hello,\nworld!"));

源码的效果,即将hello后换行显示world,如果英文翻译是:"hello,\nworld!",那么显示的效果不会发生换行效果,而是直接显示"hello,\nworld!"。

要想达到换行效果,有几种方式:

①最简单的直接在用 Qt Linguist 打开.ts文件,找到对应条目,在“翻译”文本框中直接按回车键(Enter)来换行,不要输入\n

#英文 hello, nworld! #中文 你好, 世界!

②使用 HTML 标签<br>代替\n(最可靠)

修改源码,直接在代码中将\n替换为使用 HTML 的<br>标签,并确保控件支持富文本(QLabel默认支持)。

源码

m_alarmText->setTextFormat(Qt::RichText); // 显示强制设置为富文本,大多数显示文本的控件(如 QLabel、QTextEdit、QMessageBox)默认就已经启用了富文本支持 m_alarmText->setText(tr("hello,<br>world!"));

源码中如果使用中文,中文翻译时同样用<br>

tr("你好,<br>世界!")

使用QT的Linguist翻译,翻译文本中应同样包含<br>,而不能使用回车或者\n代替<br>,也不能删除<br>

你好,<br>世界!

优点:翻译时直接写<br>,无论什么情况下都能换行,不受转义问题影响。

  • 兼容所有翻译(翻译人员直接抄<br>即可)

  • 不依赖 Qt 对\n的特殊处理

  • 未来如果需要加粗、颜色等格式也很方便

Qt 的富文本(Rich Text)常用的 HTML 标签及其含义和用法见后续章节。

方式2:使用指令提取和生成语言库

lupdatelrelease、linguist都是 Qt 官方开发工具的一部分,包含在 Qt 安装包中(Qt SDK)。 你只需要正常安装 Qt(例如通过 Qt Online Installer 或系统包管理器),这些工具就会自动安装在 Qt 的bin/目录下(如C:\Qt\6.5.0\mingw64\bin/usr/bin`)。

关键文件

  • lupdate:提取源码中的tr()字符串,生成/更新.ts翻译源文件

  • linguist:图形化编辑.ts文件,填写翻译

  • lrelease:将.ts编译为.qm二进制文件(程序运行时加载)

步骤1:运行lupdate更新.ts文件,打开终端(命令行),进入项目根目录(.pro文件所在目录),执行:

lupdate myproject.pro
  • 这会扫描所有.h.cpp.ui文件中的tr()qsTr()QT_TR_NOOP等,并将新的字符串与已有翻译合并,更新到TRANSLATIONS指定的每个.ts文件中。

  • 如果.ts文件不存在,它会自动创建。

lupdate . -ts myapp.ts – 扫描当前目录下所有源码,生成/更新 myapp.ts lupdate -no-obsolete my.pro – 丢弃源码中不再存在的“过期”条目 lupdate -extensions cpp,h,ui . -ts myapp.ts – 只指定扩展名

步骤2:使用linguist编辑翻译

以翻译成中文为例

linguist translations/myapp_zh_CN.ts
  • 在图形界面中,逐条填写翻译。

  • 完成后保存文件。

步骤3:使用lrelease生成.qm文件

lrelease myproject.pro
  • 会为每个.ts文件生成对应的.qm文件(通常放在与.ts相同目录)。

  • .qm文件体积小、加载快,用于最终部署。

lrelease myapp.pro – 处理 .pro 中 TRANSLATIONS 所有文件 lrelease myapp_zh_CN.ts -qm myapp_zh_CN.qm – 单独转换一个文件

Qt 的富文本(Rich Text)和HTML 标签

常用的 HTML 标签可以在QLabelQTextEditQMessageBox等控件中使用,以提供丰富的文本格式。

1. 文本样式

标签含义示例说明
<b>粗体<b>粗体文字</b>加粗显示
<i>斜体<i>斜体文字</i>倾斜显示
<u>下划线<u>带下划线的文字</u>文字下方加线
<s><strike>删除线<s>删除的文字</s>文字中间划横线
<big>大字号<big>放大文字</big>比默认字体大一号
<small>小字号<small>缩小文字</small>比默认字体小一号
<sup>上标X<sup>2</sup>
<sub>下标H<sub>2</sub>OH₂O

2. 字体与颜色

标签/属性含义示例
<font>字体、大小、颜色<font color="red" size="4">红色文字</font>
color属性文字颜色color="#FF0000"color="red"
size属性字号(1-7)size="5"
face属性字体名称face="Arial"

注:Qt 推荐使用 CSS 样式而非<font>标签,但两者都支持。

3. 段落与布局

标签含义示例说明
<br>换行第一行<br>第二行强制换行,不产生新段落
<p>段落<p>这是一个段落</p>段落前后会有间距
<div>块级容器<div align="center">居中内容</div>用于分组和布局
align属性水平对齐align="left/center/right"可应用于<p>,<div>,<h1>
<hr>水平分割线<hr>显示一条横线

4. 标题与列表

标签含义示例说明
<h1>~<h6>标题<h2>二级标题</h2>字号依次减小,加粗
<ul>无序列表<ul><li>项目1</li><li>项目2</li></ul>带圆点符号
<ol>有序列表<ol><li>第一项</li><li>第二项</li></ol>带数字序号
<li>列表项<ul><ol>配合使用每个项目

5. 链接与图片

标签含义示例说明
<a>超链接<a href="https://qt.io">Qt官网</a>支持点击信号(需处理linkActivated信号)
<img>图片<img src=":/images/icon.png" width="32" height="32">支持资源路径或本地文件,可设置宽高

注意:<img>QLabel中默认显示,但不会自动缩放;QTextEdit中更灵活。

6. 表格

标签含义示例
<table>表格<table border="1">...
<tr>表格行<tr><td>行1列1</td><td>行1列2</td></tr>
<td>表格单元格
<th>表头单元格(加粗居中)<th>姓名</th>

7. 常用 CSS 样式(部分支持)

Qt 富文本支持内联 CSS 样式,常用示例:

<span style="font-size:16px; color:blue; background-color:yellow;">带背景色的文字</span> <div style="margin:10px; padding:5px; border:1px solid black;">带边框的块</div>

8. 应用示例

翻译时,翻译人员只需翻译标签之间的文本内容,保留所有HTML 标签即可。

示例1:

m_statusText->setText(tr("<span style=\"color:#0082FF;\">Updating</span><br>"));
  • 作用:在控件m_statusText上显示一段富文本内容。

  • 内容

    • <span style="color:#0082FF;">定义了一个内联样式,将文字颜色设置为蓝色#0082FF)。

    • Updating是实际显示的文字(英文“更新中”)。

    • </span>结束样式作用域。

    • <br>在文本末尾添加一个换行(可能用于后续内容或布局留空)。

  • 效果:界面上会显示一行蓝色的“Updating”,然后换行(光标或后续元素移到下一行)。

翻译文本:

// 只替换需要翻译的文本,保留HTML标签 // 英文 <span style="color:#0082FF;">Updating</span><br> // 中文 <span style="color:#0082FF;">更新中</span><br>

示例2:

m_alarmText->setText(tr( "<h2>校准指引</h2>" "<p>请将设备<b>静止放置</b>在水平面上,<br>然后点击下方按钮:</p>" "<ul><li>点击 <font color=\"green\">开始</font> 进行校准</li>" "<li>点击 <font color=\"red\">取消</font> 退出</li></ul>" "<a href=\"https://example.com/help\">查看帮助</a>" ));

总结

  • 换行<br>分段<p>

  • 加粗、斜体、颜色、字号<b><i><font>或 CSS。

  • 列表、表格、图片、链接也可按需使用。

  • 多语言翻译时,只翻译标签之间的纯文本,不翻译标签本身

http://www.gsyq.cn/news/1533144.html

相关文章:

  • 2026年饲料第三方检测机构综合评述:市场格局、服务能力与案例解析 - 优质品牌商家
  • 临朐、青州短视频代运营公司怎么选,靠谱的有哪些 - 工业品网
  • Spreadsheet图表设计原理与实战:数据可视化入门必修课
  • Everything:基于USN日志的Windows极速文件名搜索工具原理与实战
  • AI岗位井喷?1亿数据揭示真相:收藏这份进阶指南,小白也能抓住大模型红利!
  • 凯撒旅业全资控股凯撒海湾,共绘海洋文旅新蓝图 - 品牌2026
  • 2026年6月市场评价高的联轴器生产厂家推荐,齿式传动轴/传动轴/球齿联轴器/挠性联轴器,联轴器实力厂家怎么选择 - 品牌推荐师
  • Kinovea运动分析软件:5分钟快速上手指南与实战技巧
  • 2026年四川火锅店制冷设备公司怎么选?行业趋势与供应商深度分析 - 优质品牌商家
  • 对比实验全流程指南:从A/B测试设计到结果分析与决策
  • Mistral Agents API:轻量级状态感知智能体工作流设计
  • DPDK高性能交换机深度实战:一次FIB更新风暴引发的转发抖动故障分析
  • 2026年工业冷却用水钻井服务商综合评估:从技术能力到本地化服务的多维解析 - 优质品牌商家
  • Proface GP-Pro EX 409汉化包:官方与民间资源解析及安全安装指南
  • Highcharts V13新功能PlotBorderRadius绘制圆角属性——生成美观的倒角图表
  • 戴尔笔记本风扇控制终极指南:16级精准调速与智能温控实战
  • 口碑好的防腐管道,迎航管道的实力 - 工业品网
  • Harness GitOps Agent安装避坑指南:网络、RBAC与HA深度解析
  • Gitlab本地服务器搭建及配置-详细教程
  • 离散数学·集合论深度学习笔记
  • LLM缝合机制揭秘:1.5%关键神经元如何驱动类推理行为
  • 彻底告懂 C++20 太空船运算符(<=>):一劳永逸的结构化比较艺术
  • 双轮驱动下的战略基石:凯撒易食如何重塑凯撒旅业的核心竞争力 - 品牌2026
  • 新手学 C 别死啃语法!第二期:吃透变量与运算符,手写简易计算器
  • 富士贴片机实用技术培训:从操作到精通的SMT核心技能
  • VC维度与样本复杂度:机器学习理论核心解析
  • AI高考数学全不及格?揭秘大模型的认知断层与评测新范式
  • 2026年靠谱的贵州亲子旅游/贵州地接旅行社TOP排行 - 行业平台推荐
  • 批量关键词批量检索,不用单次单个词检索,压缩一半操作时间
  • Python列表删除原理与生产级安全实践