• Qt 多语言


    Qt 帮助文档
    Qt5.9 c++ 开发指南

    1. 多语言介绍

    Qt 帮助文档介绍:
    Qt 多语言

    2. 多语言实现

    2.1 将 .qm 文件拷贝到构建目录

    QT 多语言无法切换问题 load失败 路径无效

    .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 &\
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    DESTDIR 设置可执行文件存放的位置,假如构建目录为H:\test\qt\build-QLabel Desktop_Qt_5_14_2_MSVC2017_32bit-Debug,在Debug模式,默认可执行文件在构建目录的子目录的debug文件夹中,如果做如下设置:

    DESTDIR += bin
    
    • 1

    则可执行文件在构建目录中建立一个bin文件夹(和 debug 文件在同一目录),可执行文件在bin目录中

    PWD 当前工程文件所在的路径
    如:工程 QLabel.pro 所在的目录为 H:\test\qt\QLabel, 则该变量的值为:

    message(PWD: $$PWD)
    
    • 1

    编译输出:

    Project MESSAGE: PWD: H:/test/qt/QLabel
    
    • 1

    注意路径中的分隔符为 Qt 的分隔符,不是 windows 分隔符,如果要转换 Windows 系统的分隔符,如下:

    #system_path(path) 将路径中的分隔符转换为系统的分隔符
    makefilePath = $$system_path($$OUT_PWD)
    message(OUT_PWD: $$OUT_PWD)
    message(makefilePath: $$makefilePath)
    
    • 1
    • 2
    • 3
    • 4

    编译输出:

    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
    
    • 1
    • 2

    DESTDIR 默认为构建目录,放置包括可执行文件的目录,上述代码会将目录设置为:

    D:\sample_code\build-demo-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug\bin
    
    • 1

    QMAKE_POST_LINK 语句中的 & 用于执行多条命令,如果后面还有命令,不管前面的命令是否执行成功都继续往后执行。(cmd-连续执行多条命令
    xcopycmd 命令,/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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    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
    
    • 1

    用 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    【Python】实现M行N列的矩阵转置
    Hexagon_V65_Programmers_Reference_Manual(28)
    redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
    象棋中的马跳步问题
    浅谈二叉树
    MAC M芯片 Anaconda安装
    如何录制微课?简单,手把手教你:教学微课视频如何录制
    [如何在VS code中使用mysql](使用sqltools插件)
    数据结构与算法(C语言版)P6---队列
    安卓常用组件(启停活动页面、活动之间传递信息、收发应用广播、操作后台服务)
  • 原文地址:https://blog.csdn.net/Lee567/article/details/126309152