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:\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跨平臺(window、linux)實現多語言