zoukankan      html  css  js  c++  java
  • Qt跨平台(window、linux)实现多语言

       在项目中,实现多语言基本山是基本需求,虽然Qt支持跨平台,但在linux和windows上实现多语言的方式还是细微区别的,废话不多说,直接进入主题吧。

      Qt实现多语言,是用过QTranslator加载文件,然后用QCoreApplication::installTranslator(m_tran)进行安装即可。在linux上,需要加载的是*.ts文件。其格式如下(language_ch.ts):

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS>
    <TS version="2.1" language="ch">
    <context>
        <message id="CON_TXT001">
            <translation>同时只做一件事,并把它做好。</translation>
        </message>
        <message id="CON_TXT002">
            <translation>中文</translation>
        </message>
        <message id="CON_TXT003">
            <translation>英文</translation>
        </message>
    </context>
    </TS>

    在window上加载的是*.qm文件,*.qm是通过*.ts转转化而来的,转步骤如下:

    1、打开window的命令窗口,进入到D:QtQt5.3.25.3mingw482_32in目录下(Qt的安装目录);

    2、将需要转化的ts文件拷贝到D:QtQt5.3.25.3mingw482_32in目录下(如language_ch.ts和language_en.ts);

    3、在window命令窗口输入 :lrelease -idbased language_en.ts,按回车键。同理输入lrelease -idbased language_ch.ts,按回车;

    4、这时在D:QtQt5.3.25.3mingw482_32in下就会生成language_ch.qm和language_en.qm。

      上面是*.ts和*.qm文件制作的方法,注意一个ts文件仅仅对应一种语言。在看看如何在代码中使用吧,我自己也写了个小demo,代码如下:

    clanguage.h  

    #ifndef CLANGUUAGE_H
    #define CLANGUUAGE_H
    
    #include <QObject>
    #include <QTranslator>
    #include <QtQml>
    #include <QQmlEngine>
    #include <QDebug>
    #include <QCoreApplication>
    #include <QQmlApplicationEngine>
    #include <QString>
    
    class CLanguuage : public QObject
    {
        Q_OBJECT
    public:
        typedef enum
        {
            LANGUAGE_CH,
            LANGUAGE_EN,
            LANHUAGE_NUM,
        }LANGUAGE_TYPE;
        Q_ENUMS(LANGUAGE_TYPE) //注册枚举到QML
    
        explicit CLanguuage(QObject *parent = 0);
        explicit CLanguuage(QQmlEngine* engine, QObject *parent = 0);
        ~CLanguuage();
    
        Q_PROPERTY(QString strTag READ getStrTag  NOTIFY strTagChanged) //注册有个属性到QML
        Q_INVOKABLE void requestChangedLanguage(LANGUAGE_TYPE type);    //注册一个方法到QMl
    
        QString getStrTag(void);
    signals:
        void strTagChanged(void);
    public slots:
    
    private:
        QQmlEngine*         m_pRoot;
        QTranslator*        m_tran;
    };
    
    #endif // CLANGUUAGE_H

    clanguage.cpp

    #include "clanguage.h"
    
    CLanguuage::CLanguuage(QObject *parent) :
        QObject(parent)
      ,m_pRoot(NULL)
    {
        m_tran = new QTranslator();
        m_pRoot->rootContext()->setContextProperty("myLanguage", this); //将C++对象作为属性注册到QML
    }
    
    CLanguuage::CLanguuage(QQmlEngine* engine, QObject *parent) :
        QObject(parent)
      ,m_pRoot(engine)
    {
        m_tran = new QTranslator();
        m_pRoot->rootContext()->setContextProperty("myLanguage", this); //将C++对象作为属性注册到QML
    }
    
    CLanguuage::~CLanguuage()
    {
        if(NULL != m_tran)
        {
            delete m_tran;
            m_tran = NULL;
        }
    }
    
    void CLanguuage::requestChangedLanguage(LANGUAGE_TYPE type)
    {
        qDebug()<<" void CLanguuage::requestChangedLanguage() type = "<<type;
        QString strPath;
        switch(type)
        {
        case CLanguuage::LANGUAGE_CH:
    #ifdef Q_OS_WIN //window
            strPath = "language_ch.qm";
    #else           //linux
            strPath = "language_ch.ts";
    #endif
            break;
        case CLanguuage::LANGUAGE_EN:
    #ifdef Q_OS_WIN
            strPath = "language_en.qm";
    #else
            strPath = "language_en.ts";
    #endif
            break;
        default:
    #ifdef Q_OS_WIN
            strPath = "language_en.qm";
    #else
            strPath = "language_en.ts";
    #endif
            break;
        }
    
        if(NULL != m_tran)
        {
            bool ret = false;
            qDebug()<<" void CLanguuage::requestChangedLanguage() strPath = "<<strPath;
            ret = m_tran->load(strPath);
    
            qDebug()<<" void CLanguuage::requestChangedLanguage() A ret = "<<ret;
            ret = false;
            ret = QCoreApplication::installTranslator(m_tran);
            emit strTagChanged();
            qDebug()<<" void CLanguuage::requestChangedLanguage() B ret = "<<ret;
        }
    }
    
    QString CLanguuage::getStrTag(void)
    {
        return "";
    }

    main.qml

    import QtQuick 2.3
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.2
    import Test.Com 1.0
    
    Window {
        visible: true
         440
        height: 360
      Button
      {
         id:chineseBtn
         220
         height:30
         text:qsTrId("CON_TXT002")+myLanguage.strTag
         onClicked:
         {
            myLanguage.requestChangedLanguage(ZH.LANGUAGE_CN)
            console.log(" zh chinese button clicked")
         }
      }
    
      Button
      {
          id:englishBtn
          x:220
          220
          height:30
          text:qsTrId("CON_TXT003")+myLanguage.strTag
          onClicked:
          {
              myLanguage.requestChangedLanguage(ZH.LANGUAGE_EN)
              console.log(" zh english button clicked.")
          }
      }
    
    
      Text {
          font.pixelSize: 24
          text: qsTrId("CON_TXT001")+myLanguage.strTag
          color: "#6e16e0"
          anchors.centerIn: parent
      }
    }

    main.cpp

    #include <QGuiApplication>
    #include "clanguage.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine* engine = new QQmlApplicationEngine();
        qmlRegisterType<CLanguuage>("Test.Com", 1, 0, "ZH"); //将C++类型注册到QML
        CLanguuage lang(engine);
        lang.requestChangedLanguage(CLanguuage::LANGUAGE_CH );
        engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }

      上面代码中,如果还不知道C++和QML联合编程的,可以看看我上一篇博客《C++和QML联合编程》。上面代码的中英文切换的主要看clanguage.cpp的:

    void CLanguuage::requestChangedLanguage(LANGUAGE_TYPE type)
    {
        qDebug()<<" void CLanguuage::requestChangedLanguage() type = "<<type;
        QString strPath;
        switch(type)
        {
        case CLanguuage::LANGUAGE_CH:
    #ifdef Q_OS_WIN //window
            strPath = "language_ch.qm";
    #else           //linux
            strPath = "language_ch.ts";
    #endif
            break;
        case CLanguuage::LANGUAGE_EN:
    #ifdef Q_OS_WIN
            strPath = "language_en.qm";
    #else
            strPath = "language_en.ts";
    #endif
            break;
        default:
    #ifdef Q_OS_WIN
            strPath = "language_en.qm";
    #else
            strPath = "language_en.ts";
    #endif
            break;
        }
    
        if(NULL != m_tran)
        {
            bool ret = false;
            qDebug()<<" void CLanguuage::requestChangedLanguage() strPath = "<<strPath;
            ret = m_tran->load(strPath);
    
            qDebug()<<" void CLanguuage::requestChangedLanguage() A ret = "<<ret;
            ret = false;
            ret = QCoreApplication::installTranslator(m_tran);
            emit strTagChanged();
            qDebug()<<" void CLanguuage::requestChangedLanguage() B ret = "<<ret;
        }
    }

    这段代码通过Qt区分系统Q_OS_WIN宏来区分是window还是linux,在window下加载qm文件,在linux下加载ts文件,然后通过调用QTranslator的load函数进行加载文言文件路径,再通过QCoreApplication::installTranslator(m_tran)加载即可。在qml中,做了2个button两切换中英文,运行效果如下:

    点击中文:                              点击英文:

    注意事项:

    1、项目编译debug或release配置的文件路径下一定要将ts和qm文件放在里面,不然是读取不到文言的;

    2、在qml中加载文言的都有句qsTrId("CON_TXT003")+myLanguage.strTag,如果仅仅是qsTrId("CON_TXT003")没有+myLanguage.strTag,运行后是什么文言,会一直显示什么文言,没有办法切换的,这是因为在仅是qsTrId("CON_TXT003"),点击切换文言是没有刷新,所以在注册一个属性strTag到qml,在文言变化的时候,发射和属性相关联的信号,如文中在clanguage.cpp中的 emit strTagChanged(),这样文言切换后,qml就会进行文言刷新。

    3、上面demo我在window上运行过,在linxu没有运行(偷懒了^^),但是我之前在linux上运行过加载ts文件,和上面的方式是一样,所以这个demo在linux上应该也是没有问题的。

    4、运行demo要求要确保运行的系统上有字体文件,就是*.ttf文件,在window上默认就是有的,但是在一些嵌入式ARM版本上,是需要人为的部署进去的。

  • 相关阅读:
    windows根据指定编码启动jar包
    Ioc/DI和Aop(2)
    SpringIOC和AOP原理 设计模式(3)
    nacos安装与基础配置
    jvm内存参数解析
    springboot集成多数据源
    linux常见命令
    idea常见问题
    GSP
    GSP
  • 原文地址:https://www.cnblogs.com/huiz/p/8135085.html
Copyright © 2011-2022 走看看