营销型网站上海制作,烟台做网站谁家好,东道设计作品,自学设计的网站QT国际化#xff08;Internationalization#xff0c;简称I18N#xff09;是指将一个软件应用程序的界面、文本、日期、数字等元素转化为不同的语言和文化习惯的过程。这使得软件能够在不同的国家和地区使用#xff0c;并且可以根据用户的语言和地区提供本地化的使用体验。… QT国际化Internationalization简称I18N是指将一个软件应用程序的界面、文本、日期、数字等元素转化为不同的语言和文化习惯的过程。这使得软件能够在不同的国家和地区使用并且可以根据用户的语言和地区提供本地化的使用体验。 QT是一种跨平台的应用程序开发框架提供了很多工具和功能来支持国际化。下面将介绍QT国际化的一些基本概念和示例代码。
一、QT国际化三部曲 lupdate更新linguist编辑lrelease发布
1、lupdate lupdate是一个命令行工具随Qt框架一起提供它的主要作用是从源代码中提取出所有的可翻译字符串并更新.ts文件Translation Source文件。.ts文件是XML格式的包含了源代码中出现的所有可翻译字符串及其对应的翻译。 lupdate的工作原理大致如下
1解析源代码lupdate遍历指定的源文件或源代码目录解析C、QML或JavaScript文件寻找所有的可翻译字符串。在C中这通常是通过tr()函数、QT_TR_NOOP()宏、QObject::tr()方法或者其他相关的Qt翻译宏来标识的。
2提取字符串当lupdate找到一个可翻译的字符串时它会提取出字符串及其上下文信息。上下文通常是包含该字符串的类名这有助于翻译人员了解字符串在应用程序中的用途。
3更新.ts文件lupdate然后将这些字符串添加到对应的.ts文件中。如果字符串已经存在它会保留现有的翻译并标记任何更改。如果字符串是新的它将被添加等待翻译。
4处理旧字符串对于在源代码中不再出现的字符串lupdate可以标记它们为“obsolete”过时的或者根据命令行参数的不同直接从.ts文件中删除。
5保存.ts文件更新后的.ts文件将包含所有从源代码中提取的字符串以及任何现有的翻译和新的、未翻译的或标记为过时的条目。 选项和参数 lupdate 提供了一些选项来控制其行为 -pro filename 指定 Qt 项目的 Pro 文件lupdate 将自动从 Pro 文件配置中查找源文件。 -ts filename [filename …] 指定输出的翻译文件可以是多个文件。 -recursive 递归地扫描目录及其子目录中的源文件。 -no-obsolete 移除翻译文件中不再存在于源代码中的条目。 -extensions extensions 指定源文件的扩展名例如 .cpp, .h, .qml。 2、linguist Linguist 是 Qt 提供的一个用于翻译和本地化的工具套件它包括三个关键的命令行工具lupdate、lrelease 和 linguist 主程序。 这些工具分别用于提取可翻译字符串、生成可执行的翻译文件以及编辑翻译文件。这里主要介绍 linguist 主程序的工作原理和使用方法。 Linguist 主程序的工作原理
1打开翻译文件Linguist 打开以 .ts 为扩展名的 Qt 翻译文件。这些文件通常由 lupdate 工具生成其中包含待翻译的字符串、上下文及其在源代码中的定位信息。
2编辑翻译条目
翻译人员可以使用 Linguist 编辑每个翻译条目的翻译内容。界面显示原始字符串和待翻译的字符串翻译人员可以直接输入相应的翻译。
3翻译状态管理Linguist 支持不同的翻译状态如“未翻译”、“已翻译”、“已校对”等帮助翻译人员和项目管理人员跟踪翻译进度和质量。
4术语库和建议Linguist 能够使用术语库和以前的翻译建议提高翻译的一致性和效率。这些建议可以从已翻译的字符串和外部的术语库文件中获得。
5语法和拼写检查Linguist 提供内置的语法和拼写检查功能提醒翻译人员可能的拼写错误或常见语法问题。
6生成二进制翻译文件翻译完成后可以通过 lrelease 工具将 .ts 文件编译成 .qm 文件供应用程序在运行时加载。
3、lrelease lrelease 是 Qt 工具链的一部分用于将 .ts (Qt 翻译源文件) 编译为 .qm (Qt 翻译二进制文件) 文件。.qm 文件用于在运行时加载翻译内容从而实现多语言支持。
lrelease 的工作原理和使用方法如下
1读取 .ts 文件lrelease 读取一个或多个 .ts 文件这些文件包含源语言字符串及其翻译内容。2解析 XML 数据.ts 文件是基于 XML 格式的文本文件lrelease 解析这些 XML 数据提取所有翻译条目信息。3生成二进制文件lrelease 将这些解析后的数据编译成高效的二进制格式 .qm 文件这些文件可以在运行时被 Qt 应用程序加载。 二、应用 Qt开发中的构建工具常用qmake和cmake。
1、使用qmake进行国际化 .pro文件中添加支持的语言
TRANSLATIONS lanague_cn.ts\lanague_en.ts
在Qt Creator中调用lupdate导出ts文件 或在命令行输入命令lupdate trans.pro -ts lanague_en.ts 然后用语言家(linguist)打开要翻译的ts文件进行编辑翻译 编辑完发布调用lrelease生成qm文件 (Qt 翻译二进制文件) 使用qm文件 QTranslator translator;translator.load(D:/QTDemo/trans/lanague_en.qm);a.installTranslator(translator); 2、使用cmake进行国际化 在CMakeLists.txt文件中添加下列代码
set(TS_FILES${CMAKE_SOURCE_DIR}/zh_CN.ts${CMAKE_SOURCE_DIR}/en_US.ts
)find_program(LUPDATE_EXECUTABLE lupdate)
find_program(LRELEASE_EXECUTABLE lrelease)foreach(_ts_file ${TS_FILES})execute_process(COMMAND ${LUPDATE_EXECUTABLE} -recursive ${CMAKE_SOURCE_DIR} -ts ${_ts_file})execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file})
endforeach()
执行CMake 三、切换语言
1、重启程序
使用QProcess类静态方法
// program, 要启动的程序名称
// arguments, 启动参数
bool startDetached(const QString program, const QStringList arguments);
示例代码
ui MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindowQT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private slots:void slotCurrentTextChanged(const QString str);private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HMainWindow.cpp
#include mainwindow.h
#include ui_mainwindow.h
#include QSettings
#include QProcessMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);ui-comboBox-addItem(简体中文);ui-comboBox-addItem(English);QSettings settings(QCoreApplication::applicationDirPath()/config.ini, QSettings::IniFormat);QString str settings.value(Set/Language).toString();if(!str.isEmpty())ui-comboBox-setCurrentText(str);connect(ui-comboBox,QComboBox::currentTextChanged,this,MainWindow::slotCurrentTextChanged);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::slotCurrentTextChanged(const QString str)
{QSettings settings(QCoreApplication::applicationDirPath()/config.ini, QSettings::IniFormat);settings.setValue(Set/Language, str);// qApp-quit();
// QProcess::startDetached(qApp-applicationFilePath(), QStringList());qApp-exit(777);
}main.cpp
#include mainwindow.h#include QApplication
#include QTranslator
#include QSettings
#include QProcessint main(int argc, char *argv[])
{QApplication a(argc, argv);QSettings settings(QCoreApplication::applicationDirPath()/config.ini, QSettings::IniFormat);QString str settings.value(Set/Language).toString();QTranslator translator;if(str English){translator.load(D:/QTDemo/trans/lanague_en.qm);a.installTranslator(translator);}MainWindow w;w.show();// return a.exec();int e a.exec();if(e 777){QProcess::startDetached(qApp-applicationFilePath(), QStringList());return 0;}return e;
}2、不重启程序 监听QEvent::LanguageChange事件当切换翻译器时会在底层发出一个LanguageChange事件所有的需要改变文本的窗口都监听这个事件。
示例代码
在窗口中重写 bool event(QEvent *event) bool MainWindow::event(QEvent *event)
{if(event-type() QEvent::LanguageChange){ui-retranslateUi(this); //重新翻译UI界面}return QWidget::event(event);
}
需要注意在加载新的语言时需要先将已绑定的语言移除。
void MainWindow::slotCurrentTextChanged(const QString str)
{static QTranslator* translator;if (translator ! NULL){//先将已绑定的语言移除qApp-removeTranslator(translator);delete translator;translator NULL;}translator new QTranslator;if(str English){translator-load(D:/QTDemo/trans/lanague_en.qm);qApp-installTranslator(translator);}
}
四、注意事项 不能直接翻译全局变量、静态变量、符号常量字符串 因为全局变量、静态变量初始化发生在QTranslator::installTranslator之前Qt无法替换翻译这些变量。而通过QT_TR_NOOP宏可以标识出静态生存期变量让Qt可以晚一些再翻译这些变量称为delayed translation 对于常量字符串、符号常量字符串它们甚至在编译时就被编译器替换好了就更不可能经QCoreApplication::translate翻译了。像下面的做法都是徒劳
#define DEFINE_MESSAGE_ QT_TR_NOOP(Failed to 1)
const char *kConstMessage QT_TR_NOOP(Failed to 2);
static const char *kStaticConstMessage QT_TR_NOOP(Failed to 3);
...QMessageBox::critical(nullptr, tr(Error), tr(DEFINE_MESSAGE_);QMessageBox::critical(nullptr, tr(Error), tr(kConstMessage);QMessageBox::critical(nullptr, tr(Error), tr(kStaticConstMessage);
...一种替代方案是通过一个类封装全局变量并将类声明Q_DECLARE_TR_FUNCTIONS宏或者继承QObject
//GlobalMessageWarpper.h
class GlobalMessageWarpper
{Q_DECLARE_TR_FUNCTIONS(GlobalMessageWarpper)
public:static QString message() { return tr(kMessage); }static const char* kMessage;
};//GlobalMessageWarpper.cpp
const char* GlobalMessageWarpper::kMessage QT_TR_NOOP(Failed to ...);...
QMessageBox::critical(nullptr, tr(Error), GlobalMessageWarpper::message());
...