QT实现多国语言的动态切换


摘要:本文论述了如何使用QT实现程序的多语系支持以及多语系的动态切换。

前沿

我们生活中用到的程序大多都是支持单一语言的,比如在中国我们用到的软件大多是汉语的,也有很少部分使用的是英语的,但是很少有软件可以实现两种语言的动态切换。不过随着近几年我国的发展支持多国语言的软件也越来越多,比如上海地铁售票机,动车组自动售票机等都是支持汉语和英语两种语言的。使用QT编程可以很容易的编写支持多国语言的软件。

QT实现多国语言支持有两种情况:

第一种:使用UI编辑器来自动生成界面,这种方式实现多语系的动态切换很容易。

第二种:不使用UI编辑器,自己通过亲自编程来设计应用程序界面,这种方式实现多语系动态切换比较繁琐,注意不是难;

下面先来介绍第一种的实现方法:

voidMainWindow::ch_language()
{
    if(this->languageState)
    {
        this->languageState=CHINESE ;
       this->translator.load("test_ch") ;
       this->pOwner->installTranslator(&(this->translator));
    }
    else
    {
        this->languageState=ENGLISH ;
       this->translator.load("test_en") ;
       this->pOwner->installTranslator(&(this->translator));
    }
}
这个函数是实现动态切换的主要程序,其中languageState是用来记录当前语言的状态,pOwnerQApplication对象,我们只需使用QTranslator加载不同的文件就可以实现多语系的动态切换。

第二种方式就不那么简单了,除了要运行上述函数外还要将将要切换的语言重新设置一遍。

voidMainWindow::langChang()
{
    if(this->langState)
    {
        this->langState=CHINESE ;
       this->translator.load("test_ch") ;
       this->pOwner->installTranslator(&(this->translator));
    }
    else
    {
        this->langState=ENGLISH ;
       this->translator.load("test_en") ;
       this->pOwner->installTranslator(&(this->translator));
    }

   this->setWindowTitle(QObject::tr("hello world"));
    this->addFileAction->setText(QObject::tr("NewFile"));
   this->langChAction->setText(QObject::tr("Chinese"));
   this->playAction->setText(QObject::tr("Play")); ;
   this->stopAction->setText(QObject::tr("Stop"));
   this->menuBar()->addMenu(QObject::tr("FIle")) ;
    this->menuBar()->addMenu(QObject::tr("Control"));
}

因此比较麻烦,特别是界面比较繁琐的时候,将是很麻烦的。

下面来讨论为什么第一种方法为什么不需要重新设置语言了。因为使用Ui时有这个函数

voidMainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);//
这里实现语言翻译器的更新。

 

 

 

下面就来看一下QT中如何制作多语言包。

实现方法:

       为了支持国际化最关键的地方是制作多国语言包,然后再实现动态切换。QT里面既可以采用命令行也可以采用Qt Creator的界面操作来生成,这里我们利用Qt Creator来生成多国语言包。基本流程是,先生成ts文件,然后生成qm文件,最后通过QTranslator类来加载qm文件,实现多语言包的切换。注意:为了更全面地实现多语言包,在程序中所有涉及到界面中的按钮或者菜单中的文字显示,都必须使用 QObject::tr("...") 的方式将显示的内容包裹起来,这样做的原因是:只有添加了QObject::tr()的标记,生成ts文件的时候程序才会认为被QObject::tr()包裹的地方是需要制作多语言的,从而在ts中预留出位置。

1> 生成ts文件

     在QT的项目文件(.pro)中添加:TRANSLATIONS = XXX.ts YYY.ts(如果是多行,则用 \ 分割)

     

     然后执行【工具】-》【外部】-》【QT语言家】-》【更新翻译(lupdate)】,如下图所示,执行完之后项目下就会生成对应的XXX.ts、YYY.ts文件。

     

     注意:如果项目中包含ui文件,如:FORMS += ZZZ.ui,则在生成的ts文件中包含所有ui文件上的字符显示,而且,在制作ui文件时默认情况下界面上的文字显示都是通过QObejct::tr(" ")包裹的,因为在默认情况下ui中的所有控件都存在一个属性:可翻译的,就代表了默认用QObject::tr()嵌套了。

2. 生成qm文件

    利用QT语言家:Linguist打开生成的ts文件,将里面需要翻译的地方写上对应的语言,如下图所示:

   

   ts文件翻译完成后,执行Qt Creator中的【工具】-》【外部】-》【QT语言家】-》【部署翻译(lrelease)】就会生成最终要用到的qm文件,如下图所示:

  

3. 加载qm语言包

     到这里qm语言包制作完成,工作就完成了一大半了。接下来的任务就是在代码中实现语言包的加载,即:根据不同的选择加载不同的语言包。    

voidLHSyncClientPrivate::InitUiByLanguage(const QString strLanguage)

{

    if (strLanguage.isEmpty())

    {

        return;

    }

 

    QString strLanguageFile;

    if (strLanguage.compare("en") ==0)

    {

        strLanguageFile = qApp->applicationDirPath()+QString("/languages/%1/%2").arg(LHT_SYNCCLIENT_VERSION_PRODOCUTNAME).arg(LHT_SYNCCLIENT_EN_FILE);

    }

    else if(strLanguage.compare("zh") == 0)

    {

        strLanguageFile =qApp->applicationDirPath() + QString("/languages/%1/%2").arg(LHT_SYNCCLIENT_VERSION_PRODOCUTNAME).arg(LHT_SYNCCLIENT_ZH_FILE);

    }

 

    if (QFile(strLanguageFile).exists())

    {

        m_translator->load(strLanguageFile);

       qApp->installTranslator(m_translator);

    }

    else

    {

        qDebug() << "[houqd]authclient language file does not exists ...";

    }

}

其中,m_translator即为QTranslator实例,在类的构造函数中赋值:m_translator = new QTranslator;实现过程很简单,就是取得语言包的绝对路径,然后利用QTranslator来加载它,最后利用qApp->installTranslator(m_translator)来安装。

4. 重新设置界面显示

    重新设置界面的显示,这一步是很多人容易忘记的一步,如果这儿被忽略了,往往就无法完成语言的切换,即:重新设置一下需要显示的元素,该过程是在上面InitUiByLanguage过程之后进行的,相关代码如下:

voidLHSyncClientPrivate::RetranslateUi()

{

    m_wgtSync->setWindowTitle(tr("DriveClient"));

       

    //! 左侧同步信息

   m_btnSynchronizing->setText(tr("Synchronizing"));

   m_btnSynchronized->setText(tr("Synchronized"));

 

    //! 右侧面板

   m_lblSyncStatus->setText(tr("looking for fileschanges..."));

   m_lblShowRecordsNum->setText(tr("There are n records..."));

    m_btnSyncOrPause->setText(tr("SyncOr Pause"));

    m_btnClearAll->setText(tr("Clearall"));

    m_btnSyncOrPause->setText(tr("SyncOr Pause"));

 

   m_btnClose->setText(tr("Close"));

    m_actSync->setText(tr("SyncInfo"));

}

实现效果:

       好了,到这里整个语言包的制作过程就基本完成了。这里还需要提及一点在网盘客户端实现时的设计思路:由于网盘在登录前和登录后可操作的菜单是不一样的,要涉及一种动态加载的方式,可以实现一个UiLoader的插件,它实现所有的窗体加载(即LoadUi()返回QWidget句柄)、菜单加载、语言切换,在这些功能中可能UiLoader插件并不完成具体的工作,而仅仅是实现信号的转发功能。同样,也需要实现一个逻辑控制插件,它负责所有的菜单逻辑,而对于每个窗体则由各自的窗体插件自行完成。多语言切换的实现效果如下:

           

切换为中文:

         

切换后效果:

       

加油,坚持每天的学习!!

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值