Qt 帮助文档
Qt5.9 c++ 开发指南
1. 多语言介绍
Qt 帮助文档介绍:
2. 多语言实现
2.1 将 .qm 文件拷贝到构建目录
.qm
语言文件必须在构建目录中与.exe
文件同一路径:
假如工程文件的路径为 D:\sample_code
,工程的名字为 demo
,
则构建的目录为 D:\sample_code\build-demo-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug
工程文件 .pro 中设置:
DESTDIR += bin
srcDir= $$system_path($$PWD)
TRANSLATIONS = demo_ch.ts\
demo_en.ts
QMAKE_POST_LINK += xcopy $$srcDir\*.qm $$DESTDIR /y/S &\
DESTDIR
设置可执行文件存放的位置,假如构建目录为H:\test\qt\build-QLabel Desktop_Qt_5_14_2_MSVC2017_32bit-Debug
,在Debug
模式,默认可执行文件在构建目录的子目录的debug
文件夹中,如果做如下设置:
DESTDIR += bin
则可执行文件在构建目录中建立一个bin
文件夹(和 debug 文件在同一目录),可执行文件在bin
目录中
PWD
当前工程文件所在的路径
如:工程 QLabel.pro
所在的目录为 H:\test\qt\QLabel
, 则该变量的值为:
message(PWD: $$PWD)
编译输出:
Project MESSAGE: PWD: H:/test/qt/QLabel
注意路径中的分隔符为 Qt
的分隔符,不是 windows 分隔符,如果要转换 Windows 系统的分隔符,如下:
#system_path(path) 将路径中的分隔符转换为系统的分隔符
makefilePath = $$system_path($$OUT_PWD)
message(OUT_PWD: $$OUT_PWD)
message(makefilePath: $$makefilePath)
编译输出:
Project MESSAGE: OUT_PWD: H:/test/qt/build-QLabel-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug
Project MESSAGE: makefilePath: H:\test\qt\build-QLabel-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug
DESTDIR
默认为构建目录,放置包括可执行文件的目录,上述代码会将目录设置为:
D:\sample_code\build-demo-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug\bin
QMAKE_POST_LINK
语句中的 &
用于执行多条命令,如果后面还有命令,不管前面的命令是否执行成功都继续往后执行。(cmd-连续执行多条命令)
xcopy
为 cmd
命令,/y
用于取消提示以确认覆盖; /S
后缀用于复制目录和子目录,但不包括空目录,此处可不需要。
注意:路径中不能有空格,如果路径有空格,则不能复制成功,可从 编译输出
中查看命令执行结果,会提示 无效的参数数目
2.2 加载翻译文件
示例:Qt5.9 c++ 开发指南 书示例 samp16_1
代码见: Qt 电子书以及源码 ,提取码:0ufw
QTranslator *translator = NULL;//翻译器
//语言类型
enum LangType
{
LANG_CH,
LANG_EN
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//获取可执行文件所在的目录
QString strAppPath = QCoreApplication::instance()->applicationDirPath();
//根据配置文件或其他方式选择要用的语言版本 demo_cn 或 demo_en
LangType type = getLanguageType();
QString strFileName("");
if (type == LANG_EN)
strFileName = "demo_en";
else
strFileName = "demo_ch";
//翻译语言的路径
QString strFilePath = QString("%1/%2.qm").arg(strAppPath).arg(strFileName);
//加载翻译语言
translator->load(strFilePath);
qApp->installTranslator(translator);
a.exec();
delete translator;
return 0;
}
3. 翻译 Qt 自带右键菜单
参考:Qt 翻译原生 widgets(QTextEdit 右键菜单等)
Qt 自带 QTextEdit 和 QLineEdit 编辑时右键菜单语言翻译为 widget.ts 文件;使用Qt自带一些对话框,如 QColorDialog 也在该语言文件中翻译。
翻译文件 widget.ts 来源位置:Qt安装文件夹内:Qt\Qt5.14.2\5.14.2\Src\qtbase\src\widgets
如 Qt 安装在 D 盘根目录,则路径为:D:\Qt\Qt5.14.2\5.14.2\Src\qtbase\src\widgets (这里安装 Qt 版本为 5.14.2)
用Qt打开 widgets.pro 工程文件,在 widgets.pro 文件最后添加如下行:
TRANSLATIONS += widgets.ts
用 Qt Linguist 打开 widgets.ts 文件修改并发布 (不用 Qt中用 工具-外部-Qt语言家 来更新发布该文件翻译)
如果将 widget.ts 添加到应用程序的工程文件中,用Qt中的 工具-外部-Qt语言家 更新翻译,则之前用 Qt 语言家打开 widgets.ts 文件后发现之前翻译的部分变灰色了?应用程序中右键菜单还是英文的。
如果要几种语言切换,可以将原始未修改的英文版本的 .ts 生成 .qm 文件,分别命名为 widgets_en.ts,和 widgets_en.qm;然后将修改后的中文版本命名为 widgets_ch.ts 和 widgets_ch.qm,将这四个文件拷到应用程序的工程目录和其他翻译文件放一起。
最后在程序中加载翻译文件:
QTranslator *translator = NULL;//翻译器
QTranslator *translatorMenu = NULL; //Qt 自带右键菜单翻译
//语言类型
enum LangType
{
LANG_CH,
LANG_EN
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//获取可执行文件所在的目录
QString strAppPath = QCoreApplication::instance()->applicationDirPath();
//根据配置文件或其他方式选择要用的语言版本
LangType type = getLanguageType();
QString strAppLangFile(""), strWidgetsLangFile("");
if (type == LANG_EN)
{
strAppLangFile= "demo_en";
strWidgetsLangFile = "widgets_en";
}
else
{
strAppLangFile= "demo_ch";
strWidgetsLangFile = "widgets_ch";
}
//加载右键菜单翻译文件
translatorMenu->load(strAppPath + "/" + strWidgetsLangFile + ".qm");
qApp->installTranslator(translatorMenu);
//翻译语言的路径
QString strFilePath = QString("%1/%2.qm").arg(strAppPath).arg(strAppLangFile);
//加载翻译语言
translator->load(strFilePath);
qApp->installTranslator(translator);
a.exec();
delete translator;
delete translatorMenu;
return 0;
}
4. 动态切换语言
参考:Qt实现动态切换语言
//移除原来的翻译文件
qApp->removeTranslator(translator);
//重新加载翻译文件,load 会丢弃原来的翻译文件
translator->load(strFile);
qApp->installTranslator(translator);
/*****************************************************
重新翻译当前页面 这个函数在 ui_filename.h 中,是有 ui 的话自动生成的,在 setupUi 函数中调用
如果有 ui 文件,则在 .cpp 文件中会有一条语句: ui->setupUi(this);
函数 retranslateUi 其实就是将 ui 界面中语言翻译,如:
Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
label->setText(QCoreApplication::translate("Widget", "label", nullptr));
pushButton->setText(QCoreApplication::translate("Widget", "button", nullptr));
因此,如果有些界面的翻译是在代码中设置的,如:
ui->label->setText(tr("label");
则 retranslateUi 不会更新该翻译,只会更新为界面设置的翻译
******************************************************/
ui->retranslateUi(this);
//如果有代码中翻译的部分,可以将这些翻译的部分放在一个函数中重新翻译一遍
updateCodeTrans();
//在更改语言的页面重新加载翻译文件,并更新该界面的翻译后,
//如果还有其他界面,则通过 changeEvent 识别修改翻译状态
void MainWindow::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
switch(e->type())
{
case QEvent::LanguageChange:
ui->retranslateUi(this);
updateCodeTrans(); //更新代码中的翻译
break;
default:
break;
}
}