项目都快做完了突然又要做多语言支持,所以得将所用的界面上的字都提取出来,虽然Qt已经自带了多语言工具了,但还是不想用自带的,毕竟这项目需要支持8种甚至更多种语言。在这个项目,我是通过读写文件的形式来读取多语言的,好在经过几天的努力终于全部都整完了,美滋滋。整完之后觉得这种方法不错,应该能适应于其他的需要支持多语言的Qt项目中,所以就先分享给大家。
源码下载:src.tar.gz
这里主要的用到了两个类:AbstractMultiLanguageString和LanguageString。
先介绍一下AbstractMultiLanguageString,这个类的功能就是保存字符串用的,如果项目中需要支持三种语言,这个类就可以保存相应字符的相应三种需要的语言,只要需要使用字符串就定义一个AbstractMultiLanguageString变量。我都是在LanguageString类中定义了整个项目中需要使用的所用字符串。我们先看一下头文件。
#define MAX_LANGUAGE 3 //语言总数
//#define LANG_INI "lang_ini" //开始的时候为了读写方便使用,之后将文件添加到资源中
#define LANG_INI ":/res/lang_ini" //保存的翻译文件
class AbstractMultiLanguageString : public QObject
{
Q_OBJECT
public:
explicit AbstractMultiLanguageString(QObject *parent = 0);
void setString(const QString &str, const int &index);
QString getString();
QString getString(const int &nIndex);
signals:
public slots:
private:
//保存不同语言的字符串,如果需要添加一种语言只需将MAX_LANGUAGE加1就可以了
QString m_String[MAX_LANGUAGE];
};
整个类其实很简单,就是保存同一意思的多种语言。在来看一下C++实现。就是setString,getString两个函数。setString设置对应的语言,getString 可以获取指定的语言,和获取当前设置语言的字符串。其中MAX_LANGUAGE是支持的语言数,g_nLanguage是一个全局变量,表示当前是什么语言。
AbstractMultiLanguageString::AbstractMultiLanguageString(QObject *parent) : QObject(parent)
{
}
void AbstractMultiLanguageString::setString(const QString &str, const int &index)
{
if (index < 0 || index >= MAX_LANGUAGE)
{
return;
}
m_String[index] = str;
}
QString AbstractMultiLanguageString::getString()
{
return m_String[g_nLanguage];
}
QString AbstractMultiLanguageString::getString(const int &nIndex)
{
if (nIndex > MAX_LANGUAGE || nIndex < 0)
{
return m_String[0];
}
return m_String[nIndex];
}
接下来介绍另一个类LanguageString,这个类跟项目相关的,需要根据自己的项目来做一些相应的修改,这个类将所用要使用到的字符串统一分界面来管理,保存到相应的QVector里。程序启动的时候就是通过它来实现将所用的字符串从指定的文件中读取出来。这里我是写类一个简单的例子。分了五类,主界面,Page1-4。先看看效果图。
中文版:
英文版:
下面是头文件和实现文件。
class LanguageString : public QObject
{
Q_OBJECT
public:
explicit LanguageString(QObject *parent = 0);
void initLanguageString();
public:
QString getMainWindowString(const int &index);
QString getFunctionPage1String(const int &index);
QString getFunctionPage2String(const int &index);
QString getFunctionPage3String(const int &index);
QString getFunctionPage4String(const int &index);
private:
void initMainWindow();
void initFunctionPage1();
void initFunctionPage2();
void initFunctionPage3();
void initFunctionPage4();
signals:
public slots:
public:
/*
* MainWindow
* 0 "多语言例子"
* 1 "中文"
* 2 "下一页"
* 3 "上一页"
*/
QVector<AbstractMultiLanguageString *> m_strMainWindow;
/*
* Page1
* 0 "功能页1"
* 1 "标签"
* 2 "测试"
* 3 "其他"
*/
QVector<AbstractMultiLanguageString *> m_strFunctionPage1;
/*
* Page2
* 0 "功能页2"
* 1 "按钮"
* 2 "设置"
* 3 "取消"
*/
QVector<AbstractMultiLanguageString *> m_strFunctionPage2;
/*
* Page3
* 0 "功能页3"
* 1 "确定"
* 2 "设置"
* 3 "删除"
*/
QVector<AbstractMultiLanguageString *> m_strFunctionPage3;
/*
* Page4
* 0 "功能页4"
* 1 "插入"
* 2 "更新"
* 3 "提示"
* 4 "错误"
*/
QVector<AbstractMultiLanguageString *> m_strFunctionPage4;
};
简单介绍一下,成员变量 QVector<AbstractMultiLanguageString *> m_strXXXX;分功能或者分界面管理的字符串数组,这里是分界面来管理的。使用到了:m_strMainWindow,m_strFunctionPage1,m_strFunctionPage2,m_strFunctionPage3,m_strFunctionPage4。大家看一下图片就应该能理解了。
成员函数:void initXXXX();函数用于初始化m_strXXXX数组中的数据。
成员函数:QString getXXXXString(const int &index);得到相应的m_strXXXX下标的数据。
成员函数:initLanguageString();总的初始化函数。
部分函数实现,其他函数实现方法类似,就不一一贴上去了。
LanguageString::LanguageString(QObject *parent) : QObject(parent)
{
//initLanguageString();
}
void LanguageString::initLanguageString()
{
initMainWindow();
initFunctionPage1();
initFunctionPage2();
initFunctionPage3();
initFunctionPage4();
}
void LanguageString::initMainWindow()
{
m_strMainWindow.clear();
QString strFile = LANG_INI;
QSettings settings(strFile,QSettings::IniFormat);
settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
QString strGroup;
int nCount = 0;
QStringList strList;
strList << "多语言例子" << "中文" << "下一页" << "上一页";
QString strValue;
nCount = strList.size();
for (int i=0; i<nCount; i++)
{
AbstractMultiLanguageString *string = new AbstractMultiLanguageString;
strGroup = QString("MainWindow%1").arg(i);
//将信息写入配置文件
settings.beginGroup(strGroup);
for (int j=0; j<MAX_LANGUAGE; j++)
{
strValue = settings.value(QString::number(j), strList[i]).toString();
string->setString(strValue, j);
}
settings.endGroup();
m_strMainWindow.push_back(string);
}
#if 1
for (nCount=0; nCount<strList.size(); nCount++)
{
qDebug() << nCount << strList[nCount];
strGroup = QString("MainWindow%1").arg(nCount);
//将信息写入配置文件
settings.beginGroup(strGroup);
for (int i=0; i<MAX_LANGUAGE; i++)
{
settings.setValue(QString::number(i), m_strMainWindow[nCount]->getString(i));
}
settings.endGroup();
}
#endif
}
void LanguageString::initFunctionPage1()
{
m_strFunctionPage1.clear();
QString strFile = LANG_INI;
QSettings settings(strFile,QSettings::IniFormat);
settings.setIniCodec(QTextCodec::codecForName("UTF-8"));
QString strGroup;
int nCount = 0;
QStringList strList;
strList << "功能页1" << "标签" << "测试" << "其他";
QString strValue;
nCount = strList.size();
for (int i=0; i<nCount; i++)
{
AbstractMultiLanguageString *string = new AbstractMultiLanguageString;
strGroup = QString("FunctionPage1_%1").arg(i);
//将信息写入配置文件
settings.beginGroup(strGroup);
for (int j=0; j<MAX_LANGUAGE; j++)
{
strValue = settings.value(QString::number(j), strList[i]).toString();
string->setString(strValue, j);
}
settings.endGroup();
m_strFunctionPage1.push_back(string);
}
#if 1
for (nCount=0; nCount<strList.size(); nCount++)
{
qDebug() << nCount << strList[nCount];
strGroup = QString("FunctionPage1_%1").arg(nCount);
//将信息写入配置文件
settings.beginGroup(strGroup);
for (int i=0; i<MAX_LANGUAGE; i++)
{
settings.setValue(QString::number(i), m_strFunctionPage1[nCount]->getString(i));
}
settings.endGroup();
}
#endif
}
QString LanguageString::getMainWindowString(const int &index)
{
if (index < 0 || index >= m_strMainWindow.size())
{
return QString("");
}
return m_strMainWindow[index]->getString();
}
QString LanguageString::getFunctionPage1String(const int &index)
{
if (index < 0 || index >= m_strFunctionPage1.size())
{
return QString("");
}
return m_strFunctionPage1[index]->getString();
}
这里的#if 1主要是在项目还没有完成是将需要的字符串一中文的形式写入到文件。当将所有的字符串初始化好以后就可以将#if 1 改成#if 0,就没有必要每次启动都写文件,同时将lang_ini文件以资源文件的形式添加到工程中。下面是生成的翻译文件截图和翻译好的英文截图。
下面介绍一下mian.cpp。这里主要是定义了两个全局变量。g_nLanguage,g_LangString。
//当前设置的语言
int g_nLanguage = 0;
//项目中用到的所用的字符串
LanguageString g_LangString;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
g_LangString.initLanguageString();
MainWindow w;
w.show();
return a.exec();
}
最后介绍一个Page的实现,其它Page的实现类似。
Page1的头文件
class FunctionPage1 : public QWidget
{
Q_OBJECT
public:
explicit FunctionPage1(QWidget *parent = 0);
~FunctionPage1();
void updateString();
protected:
void showEvent(QShowEvent *event);
private:
Ui::FunctionPage1 *ui;
};
Page1的实现
extern LanguageString g_LangString;
FunctionPage1::FunctionPage1(QWidget *parent) :
QWidget(parent),
ui(new Ui::FunctionPage1)
{
ui->setupUi(this);
QPalette pal = this->palette();
pal.setColor(QPalette::Background, QColor(182,182,183));
setAutoFillBackground(true);
setPalette(pal);
}
FunctionPage1::~FunctionPage1()
{
delete ui;
}
void FunctionPage1::showEvent(QShowEvent *event)
{
updateString();
QWidget::showEvent(event);
}
void FunctionPage1::updateString()
{
//一开始的时候我是这样来或取字符串的,但后来发现这样很容易越界,
//所以就加了一个QString getXXXXString(const int &index)函数来或取字符串。
//ui->labelFunc1->setText(g_LangString.m_strFunctionPage1[0]->getString());
ui->labelFunc1->setText(g_LangString.getFunctionPage1String(0));
ui->label->setText(g_LangString.getFunctionPage1String(1));
ui->label_2->setText(g_LangString.getFunctionPage1String(2));
ui->label_3->setText(g_LangString.getFunctionPage1String(3));
}
好了,到这里就差不多了。希望这个对需要做多语言的朋友有所帮助,少走弯路。