博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt和QML如何实现国际化
阅读量:6319 次
发布时间:2019-06-22

本文共 7503 字,大约阅读时间需要 25 分钟。

版权声明:本文系作者原创。未经许可,不得转载。

本文以skytree-compositor程序为例,讲解如何将程序翻译为多种语言。    在界面中,点击“设置”,更改“语言”时,dbus会向上层发送一个信号valueChanged,上层应用响应该信号,就可以实时更改语言。1、从dbus读取语言改变的信号和系统使用的语言名称。类CmosTranslate使用了Qt自带的QTranslator类,并添加了读取dbus的功能。实现了封装,供其他程序使用。一共两个文件。代码如下:CmosTranslate.h文件#ifndef CmosTranslate_H#define CmosTranslate_H#include 
#include
#include
/**
  • 这个类根据dbus发出的信号,从dbus读取当前语言名称,实时改变程序的语言

    */

  1. CmosTranslate : public QObject

    {

    Q_OBJECT   Q_DISABLE_COPY(CmosTranslate)   Q_PROPERTY(QString name READ name WRITE setname NOTIFY nameChanged)   Q_PROPERTY(QString path READ path WRITE setpath NOTIFY pathChanged)   Q_PROPERTY(QString transflag READ transflag NOTIFY transflagChanged)

    public:

    CmosTranslate(QObject *parent = 0);   ~CmosTranslate();   //获取程序名称   QString name() {       return m_name;   }   //设置程序名称   void setname(QString value) {       m_name = value;       emit nameChanged(m_name);   }   //获取多语言文件存放的路径   QString path() {       return m_path;   }   //获取多语言文件存放的路径   void setpath(QString value) {       m_path = value;       emit pathChanged(m_path);   }   QString transflag() { return ""; }
  2. slots:

    void readData(const QString &domain, const QString &key, const QDBusVariant &value);   //根据读取的语言名称,载入相应的翻译文件   void trans(QString names="");   bool appQuit();

    Q_SIGNALS:

    void nameChanged(const QString &);   void pathChanged(const QString &);   void langChanged(const QString &);   void transflagChanged();

    private:

    //程序名称   QString m_name;   //翻译文件存放路径   QString m_path;   QString m_selfcmd;   QTranslator m_translator;   // 静态方法

    public:

    /**
    • 获取单实例

      *

    • 指向单实例的指针

      */

    1. CmosTranslate *instance();

      };

#endif // CmosTranslate_H

CmosTranslate.cpp文件

#include "CmosTranslate.h"

#include <QtDBus/QtDBus>
#include <QApplication>

QString SETTING_SERVICE_NAME = "cn.cmos.settings.Database";

QString SETTING_OBJECT_PATH = "/";

QString SETTING_INTERFACE_NAME= "cn.cmos.settings.Database";

QString APP_PATH = qgetenv("APPDIR_SYSTEM");

QString LIBRARY_PATH = "/usr/share/library/";

//如果没有设置路径,则默认为qm路径

QString TRANSLATIONS_PATH = "qm";

QString DOMAIN_VALUE = "cn.cmos.settings.Locale";

QString KEY_VALUE = "SYSTEM_LANGUAGE";

//设置该程序的默认的翻译文件存放路径

QString QM_FILE_PATH = "/usr/share/translations";

CmosTranslate::CmosTranslate(QObject *parent):

QObject(parent)

{

QFile file("/proc/self/cmdline");   file.open(QIODevice::ReadOnly | QIODevice::Text);   m_selfcmd = file.readAll();   m_selfcmd= m_selfcmd.left(m_selfcmd.lastIndexOf( QDir::separator() ) );   m_selfcmd= m_selfcmd.left(m_selfcmd.lastIndexOf( QDir::separator() ) );   m_name = QApplication::applicationName();   m_path = QM_FILE_PATH;   //将dbus的信号与程序连接   QDBusConnection::sessionBus().connect(SETTING_SERVICE_NAME, SETTING_OBJECT_PATH,                                         SETTING_INTERFACE_NAME, "valueChanged" ,this,                                         SLOT(readData(QString, QString, QDBusVariant)));

}

CmosTranslate::~CmosTranslate()
{
}

CmosTranslate::trans(QString names)

{

QString name =names;   if(name.isEmpty()) {       //调用dbus的相应方法,读取当前语言名称       QDBusMessage m = QDBusMessage::createMethodCall(SETTING_SERVICE_NAME,                                                       SETTING_OBJECT_PATH,                                                       SETTING_INTERFACE_NAME,                                                       "value");       m << "cn.cmos.settings.Locale" << "SYSTEM_LANGUAGE" <<  QVariant::fromValue(QDBusVariant("zh_CN")) ;       QDBusReply
value = QDBusConnection::sessionBus().call(m); name = value.value().variant().toString(); } if(name.isEmpty()) { name = "zh_CN"; } QString fileName = m_name + "." + name; QString path = m_path; /**如果系统和程序都没有设置,则到默认路径下寻找翻译文件
  • 如果应用程序存在,则默认路径为/usr/qm;

  • 否则默认路径为/usr/share/library

    */ if(path.isEmpty()) {     if(m_name == QApplication::applicationName()) {         path = m_selfcmd + QDir::separator()
    • TRANSLATIONS_PATH + QDir::separator();

      }
  1. {

    path = LIBRARY_PATH;    }}qDebug()<<"当前语言名称:"<
    <<"翻译文件存放路径:"<
    << "翻译文件名称:"<
  2. = "en_US";

    }//向程序发出语言改变的信号,这是对dbus信号的封装
  1. langChanged(name);

  2. transflagChanged();

    }

CmosTranslate::readData(const QString &domain, const QString &key, const QDBusVariant &value)

{

if(domain == DOMAIN_VALUE && key == KEY_VALUE){       QString name = value.variant().toString();       trans(name);   }

}

CmosTranslate::appQuit()

{

QDBusMessage m = QDBusMessage::createMethodCall("com.nomovok.skytree.compositor",                                                   "/Compositor",                                                   "com.nomovok.skytree.CompositorInterface",                                                   "appQuit");   m <
(QCoreApplication::applicationPid()); QDBusReply
back = QDBusConnection::systemBus().call(m); return back.value();

}

/

  • 静态方法

    /
    /**

  • 获取单实例

    *

  • 指向单实例的指针

    */
    CmosTranslate *CmosTranslate::instance()

{

static CmosTranslate *instance = 0;   if (!instance)   {       instance = new CmosTranslate;   }   return instance;

}

2、在主程序中增加组件

main.cpp文件

#include "CmosTranslate.h"

……

main(int argc, char *argv[]) {

……

QQmlEngine engine;
……
//向QML端添加组件

engine.rootContext()->setContextProperty("cmostranslate", CmosTranslate::instance());

……

}

3、在qml文件中响应该组件发出的信号

CancelButton.qml文件

QtQuick 2.0

//定义关机界面底部的“取消”按钮
Rectangle {

id: cancelButton              anchors.fill: parent              Text {           id:cancelLabel                       anchors.centerIn: parent           font.pixelSize : 30       }              //该控件的信号       signal languageChanged(string name)       //该控件的相应信号的响应函数       onLanguageChanged: {           translator()       }       //构造函数       Component.onCompleted: {           // 连接组件信号和控件的槽           cmostranslate.langChanged.connect(cancelButton.languageChanged)           // 调用组件函数初始化语言名称           cmostranslate.trans();       }       //析构函数       Component.onDestruction: {           //断开组件信号和控件槽           cmostranslate.langChanged.disconnect(cancelButton.languageChanged);       }       //翻译       function translator() {           cancelLabel.text = qsTr("CANCEL")       }   }

4、修改pro文件,将CmosTranslate.h和CmosTranslate.cpp加入到编译选项中,以及设置qm文件的路径。此路径必须与CmosTranslate.cpp中设置的路径一致。为了防止修改时出现不一致的情况,可以略作改进。如:可以在某个配置文件中统一设置,其他文件获取该配置。

skytree-compositor.pro文件

……

HEADERS += CmosTranslate.h
SOURCES += CmosTranslate.cpp
……

# translate

TARGET_DIR = /usr/share/translations
qm.path = $$TARGET_DIR
qm.files = *.qm
INSTALLS += qm

5、修改spec文件。在spec文件中,将qm文件配置成安装时装载到指定路径。

此路径必须与CmosTranslate.cpp中设置的路径一致。为了防止修改时出现不一致的情况,可以略作改进。如:可以在某个配置文件中统一设置,其他文件获取该配置。

skytree-compositor.spec文件

……

%files
/usr/share/translations/%{name}.zh_CN.qm
……

6、生成qm文件。在应用程序根目录,即pro文件和spec文件所在的目录。用Qt的工具lupdate、linguist、lrelease 生成ts文件和qm文件。ts文件和qm文件的命名规则必须和CmosTranslate.cpp中设定的一致,否则会找不到文件,无法载入。本程序中命名规则为:程序名.语言名.后缀名。

$ lupdate . -ts skytree-compositor.zh_CN.ts

递归抓取程序中所有需要翻译的字符串。Ts文件内容:

skytree-compositor.zh_CN.ts文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE TS>
<TS version="2.0" language="zh_CN">
<context>

CancelButton
CANCEL

</context>

</TS>

$ linguist skytree-compositor.zh_CN.ts

将字符串翻译完成,保存退出。此时,ts文件内容有改变:

skytree-compositor.zh_CN.ts文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE TS>
<TS version="2.0" language="zh_CN">
<context>

CancelButton
CANCEL
取消

</context>

</TS>

$ lrelease skytree-compositor.zh_CN.ts

将翻译好的ts文件生成qm文件。qm文件不是文本格式。

你可能感兴趣的文章
IDEA 修改JSP和后端数据后,页面刷新可以实时更新
查看>>
IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie路径问题
查看>>
synchronized(this)(转)
查看>>
类别标签处理
查看>>
深度|余凯:基于深度学习的自动驾驶之路
查看>>
ORA-00845: MEMORY_TARGET not supported on this system
查看>>
数据库存储结构
查看>>
国内银行CNAPS CODE 查询 苹果开发者,应用内购,需要填写税务相关信息必须的...
查看>>
Linux下抓图工具shutter
查看>>
javascript获取select,checkbox,radio的值
查看>>
Metro Win8风格的按钮(Filp翻转)
查看>>
cookies/session/token
查看>>
清除代码异味
查看>>
【转】从知乎上看到“全栈开发者”讨论之后的自黑
查看>>
Java-IO流
查看>>
Linux入门-6 Linux网络基本配置
查看>>
洗礼灵魂,修炼python(22)--自定义函数(3)—函数作用域,闭包
查看>>
newcoder Tachibana Kanade Loves Probability(小数点后第k位)题解
查看>>
vue项目未加载完成前显示loading...
查看>>
leetcode981
查看>>