ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

QT实现多语言并动态切换

2022-09-08 08:31:44  阅读:256  来源: 互联网

标签:en zh 语言 CN language 切换 action 动态 QT


本文讲述在QT中动态切换多语言.
我会动态生成一个菜单,这个菜单会列出所有的语言,用户可以单选一种语言,选择语言后,界面就会切换到指定的语言

1.兜底的语言
当一个语言(字符串)没有被翻译时,他会用你代码中的语言(字符串)来显示, 这个语言(字符串)就是兜底的语言.
也就是说,如果你编码的菜单,字符串等用的是中文,我们就认为兜底的语言是中文
如果你编码的菜单,字符串用的是英文,那我们就认为兜底的是英文.
强烈建议,您用英文进行编码(兜底的语言是英文),我测试的情况是,如果用中文,生成的ts文件乱码!没测试QT5,不知道QT5是否会有同样的问题,乱码图片如下:

2.编码中的需要使用多语言的地方请用tr("")包围
比如: xxxCtrl->setText(tr("您好"));
用tr("")包围是告诉QT,这个字符串要当多语言来处理

3.菜单等QT设计器上输入的文本,已经被tr("")包围了,不用管

现在我们就来一步一步地实现多语言吧

a).编辑.pro文件,增加多个ts,在我们的实例中,我们要实现两个语言,一个是zh_CN,一个是en_US,如下:

TRANSLATIONS += res/language/zh_CN.ts \
                res/language/en_US.ts

注意:这里的res/language/是表示要生成ts的目录,你也可以不写res/language/那生成的ts文件就和pro在同一个目录下.
        如果你写了res/language/或者其他什么目录,你就需要手动创建这两个文件夹,res和.pro文件同一目录,language在res目录下
编辑好的样子如图:

b). 先用界面设计器设计两个菜单,一个是File,一个是Help,
然后拖两个控件上去,一个是lable,一个是LineEdit
lable用于静态显示一个文本,设置内容为"Static Text"
LineEdit用于编码显示文本,在代码中设置内容为"Dynamic Text 100"
差不多就是下面这个样子

void MainWindow::UpdateDynamicControls()
{
    QString strText = QString(tr("Dynamic Text %1")).arg(m_nValue);
    ui->lineEditDynamic->setText(strText);
}

c). 还记得我们的a)步骤吗,现在我们就要生成这两个ts文件了,方法如下:
工具->外部->QT语言专家->更新翻译

执行完后,就会生成en_US.ts和zh_CN.ts两个文件了,不妨可以打开看看,是个xml文件,记录了所有要翻译的文本和他们所在的位置.
此时两个文件是一模一样的,为啥呢? 因为虽然QT支持多语言,但翻译还是得我们自己来....

d). 翻译
找到Linguist,通常在QT的安装目录下的bin文件中,我是直接在开始中搜索到的(位于C:\Qt\4.8.6\bin\linguist.exe)

执行,后打开zh_CN.ts,开始翻译成英文的工作.
在弹出的对话框中,目标语言已经设置好了,就是Chinese

确定后就一个一个地翻译,如果某个你不想翻译,那也没有关系,就显示"兜底"显示的内容

翻译完了后,保存一下.退出.


d). 发布翻译,生成qm文件
工具->外部->QT语言专家->发布翻译

执行后,会生成两个文件,一个是zh_CN.qm一个是en_US.qm
生成的qm文件才是最终使用的文件.

e). 程序启动的时候,加载qm文件.
把zh_CN.qm和en_US.qm加到资源文件中去(您也可以不加入到资源文件,只要exe最终能找到qm文件就可以了)
加载后如图所示

程序启动的时候,需要加载.qm文件,加载的代码如下

void MyMultiLanguage::Switch(QString strNewLang)
{
    if (0 != m_strCurLanguage.compare(strNewLang))
    {
        QString strQM = QString(":/res/language/%1.qm").arg(strNewLang);

        if (QFile(strQM).exists())
        {
            QTranslator* translator = new QTranslator;
            if (translator->load(strQM))
            {
                m_strCurLanguage = strNewLang;

                if (NULL != m_translator)
                {
                    qApp->removeTranslator(m_translator);
                    delete m_translator;
                }

                m_translator = translator;
                qApp->installTranslator(m_translator);
            }
            else
            {
                delete translator;
                translator = NULL;
            }
        }

    }
}

这段代码并不复杂,代码几乎不言自明
比如传入的参数是zh_CN
那么就先判断":/res/language/zh_CN.qm"是否存在
如果文件存在,则new 一个QTranslator(QTranslator就什么呢?你这么理解好了,一个QTranslator就是一个qm)
如果QTranslator load成功,则把原来的QTranslator删除(removeTranslator,如果有的话),加载最新的QTranslator
最后,安装多语言依赖QApplication
qApp->installTranslator(m_translator);


加载翻译这段代码(g_MultiLanguage.Init("zh_CN");)在函数入口处(QApplication后)执行

int main(int argc, char *argv[])
{
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");    //获取系统编码
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);


    QApplication a(argc, argv);

    //初始化多语言, 切换多语言依赖于QApplication
    g_MultiLanguage.Init("zh_CN");

    MainWindow w;
    w.show();

    int nRet = a.exec();

    //反初始化
    g_MultiLanguage.UnInit();

    return nRet;
}

运行,因为我们默认加载的是zh_CN.qm,所以运行界面显示为中文了,如下:

f). 加入顶层菜单language,供用户切换语言,代码如下:

    //在帮助之前,动态插入菜单language
    QMenu *languageMenu = new QMenu(tr("language"), menuBar());
    menuBar()->insertMenu(ui->menuHelp->menuAction(), languageMenu);

    //action_zh_CN = new QAction(QIcon(":/res/language/zh_CN.png"), "简体中文", this);
    //action_en_US = new QAction(QIcon(":/res/language/en_US.png"), "英文", this);

    //菜单项"简体中文",注意没有用tr包围
    QAction* action_zh_CN = new QAction("简体中文", this);
    action_zh_CN->setData("zh_CN");
    action_zh_CN->setCheckable(true);

    //菜单项"English",注意没有用tr包围
    QAction* action_en_US = new QAction("English", this);
    action_en_US->setData("en_US");
    action_en_US->setCheckable(true);

    //根据当前的语言设置选中菜单
    if (0 == g_MultiLanguage.GetCurLanguage().compare("zh_CN"))
    {
        action_zh_CN->setChecked(true);
    }
    else if (0 == g_MultiLanguage.GetCurLanguage().compare("en_US"))
    {
        action_en_US->setChecked(true);
    }

    //将简体中文和英文加入到language菜单中去,并设置好处理函数OnLanguageChanged
    QActionGroup* languageGroup = new QActionGroup(this);
    languageMenu->addAction(languageGroup->addAction(action_zh_CN));
    languageMenu->addAction(languageGroup->addAction(action_en_US));
    connect(languageGroup, SIGNAL(triggered(QAction *)), this, SLOT(OnLanguageChanged(QAction *)));

执行结果如下:

注意一下,我并没有把两个菜单项目"简体中文"和"English"用tr包围,因为这两个是不需要翻译的,他本身就代表用户要选择的语言.
处理语言切换的slot代码如下:

void MainWindow::OnLanguageChanged(QAction* action)
{
    if (NULL != action) {
        // load the language dependant on the action content
        //loadLanguage(action->data().toString());
        //setWindowIcon(action->icon());
        qDebug() << action->data().toString() << "\n";
        g_MultiLanguage.Switch(action->data().toString());
    }
}

g). 到此,我们离成功非常接近了.
我们切换语言时,会调用 qApp->installTranslator(m_translator); 这个函数会导致QEvent :: LanguageChange被发射出来
我们可以在这个事件的处理函数中,重新更新UI,完成多语言切换.
我们需要继承实现virtual void changeEvent(QEvent * event);

void MainWindow::changeEvent(QEvent * event)
{
    if (NULL != event) {
        switch (event->type()) {
            // this event is send if a translator is loaded
        case QEvent::LanguageChange:
            qDebug() << "case QEvent::LanguageChange" << endl;
            ui->retranslateUi(this);
            UpdateDynamicControls();
            break;
        default:
            break;
        }
    }
    QMainWindow::changeEvent(event);

}

最后这一步也是关键的一步,执行了两个函数:
ui->retranslateUi(this);这个函数是系统控件重新更新UI(语言)
UpdateDynamicControls();是我自己写的函数,也是动态去更新LineEdit的内容(语言),代码如下:

void MainWindow::UpdateDynamicControls()
{
    QString strText = QString(tr("Dynamic Text %1")).arg(m_nValue);
    ui->lineEditDynamic->setText(strText);
}

到此,切换语言工作完成!用户就可以在菜单里面选择自己想要的语言啦!

切换语言的调试输出:
"en_US"
case QEvent :: LanguageChange
说明每切换一次语言,就会收到QEvent :: LanguageChange一次

代码见:  http://q1024.com/files/qt_window-master.zip   000400目录
参考:https://wiki.qt.io/How_to_create_a_multi_language_application

[思考]
顶层菜单language没有翻译,不能切换语言,你知道怎么操作完成这个项目的翻译和语言切换吗?

标签:en,zh,语言,CN,language,切换,action,动态,QT
来源: https://www.cnblogs.com/xingzaicpp/p/16667969.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有