Qt跨平台(windowlinux)实现多语言

Posted Clark

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt跨平台(windowlinux)实现多语言相关的知识,希望对你有一定的参考价值。

   在项目中,实现多语言基本山是基本需求,虽然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:\\Qt\\Qt5.3.2\\5.3\\mingw482_32\\bin目录下(Qt的安装目录);

2、将需要转化的ts文件拷贝到D:\\Qt\\Qt5.3.2\\5.3\\mingw482_32\\bin目录下(如language_ch.ts和language_en.ts);

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

4、这时在D:\\Qt\\Qt5.3.2\\5.3\\mingw482_32\\bin下就会生成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
    width: 440
    height: 360
  Button
  {
     id:chineseBtn
     width: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
      width: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版本上,是需要人为的部署进去的。

 

以上是关于Qt跨平台(windowlinux)实现多语言的主要内容,如果未能解决你的问题,请参考以下文章

QML程序实现动态切换多语言(ListModel/ListElement中的文本的多语言处理)

Qt系列文章之三十九(Qt多语言国际化程序实例设计实现)

Qt系列文章之三十九(Qt多语言国际化程序实例设计实现)

请教QT中多语言切换,lupdate提取字符串不成功的问题

低代码平台多语言国际化(i18n)技术方案

.NET CORE 多语言实现方案