QT国际化遇到问题总结

多语言的必要性

 

国际化的需求

随着我们软件的业务发展,对软件产品做国际化要求也是必经之路,国际化的需求也表明我们的软甲正在变的强大。如何做好国际化?国际化中有哪些需要我们注意的地方?这些都是我们开发者要注意的问题,对于一些UI交互和直接的展示更是需要优秀的产品经理以及UI设计师去严格规范把控这些问题。

国际化的主要问题:

  • 页面的展示问题。
  1. 翻译文件过长问题,展示框展示不完整内容。

        比如:回放配置的高速配置是否开启,翻译后无法展示完全。

        客户端门户的菜单描述信息展示,最多只能展示两行,多余无法展示。

        解决方法:1.对描述性文字进行不完全展示。2.精简缩短描述文字的长度。

  • 交互不规范性,如时间的格式问题。
  • 语言翻译问题。
    1. 语句翻译的注意精简以及本土化。
    2. 注意翻译格式
  • 夏令时问题
    1. 对于支持夏令时国家和不使用夏令时国家做处理。

                   如:回放组件,视频录像条的展示需要考虑是否显示夏令时的格式。部分逻辑也要做特殊处理,否则造成显示的数据错误问题。


多语言的解决方案

多语言的翻译问题是国际化中最直接和主观的,所以对于国际化中多语言的文字展示需要找到统一的解决方案,可以使用很多框架提供的方法,但是在我看来本质都是一样的。都是在展示文本时候,通过读取翻译文件从而对应显示正确的内容。在我们的云远客户端中使用的是QT的国际化解决方案。主要是涉及到翻译文件的创建,载入,卸载等。下面会针对从如何创建.ts文件,到最后在界面展示正确的内容做简单介绍。

如何搭建多语言模块

翻译文件的介绍

 

翻译文件的创建和使用

  • VS2015使用插件创建.ts文件。

1.创建TS文件

             

2.更新ts文件

3.打开修改翻译文件

 

 

 

  • Qt Creator 创建和使用.ts文件

1.创建文件

2.更新ts文件

3.打开修改ts翻译文件


 

UI的刷新相关原理介绍。

先看下下面一段话:

Adds the translation file \a translationFile to the list of

    translation files to be used for translations.

    Multiple translation files can be installed. Translations are

    searched for in the reverse order in which they were installed,

    so the most recently installed translation file is searched first

    and the first translation file installed is searched last.

    The search stops as soon as a translation containing a matching

    string is found.

    Installing or removing a QTranslator, or changing an installed QTranslator

    generates a \l{QEvent::LanguageChange}{LanguageChange} event for the

    QCoreApplication instance. A QApplication instance will propagate the event

    to all toplevel widgets, where a reimplementation of changeEvent can

    re-translate the user interface by passing user-visible strings via the

    tr() function to the respective property setters. User-interface classes

    generated by Qt Designer provide a \c retranslateUi() function that can be

    called.

通过这段话可以看出,UI的语言切换,需要重新卸载和载入文件和安装的过程。安装好后会下发QEvent::LanguageChange事件。在UI文件中会自动调用retranslateUi()函数,通过这段话,我们就知道怎么使用多语言文件了。

 

 

相关事件的下发

安装翻译文件:installTranslator

bool QCoreApplication::installTranslator(QTranslator *translationFile)

{

    if (!translationFile)

        return false;

    if (!QCoreApplicationPrivate::checkInstance("installTranslator"))

        return false;

    QCoreApplicationPrivate *d = self->d_func();

    d->translators.prepend(translationFile);



#ifndef QT_NO_TRANSLATION_BUILDER

    if (translationFile->isEmpty())

        return false;

#endif


#ifndef QT_NO_QOBJECT

    QEvent ev(QEvent::LanguageChange);

    QCoreApplication::sendEvent(self, &ev);

#endif

    return true;

}

 

 

 

移除翻译文件

bool QCoreApplication::removeTranslator(QTranslator *translationFile)

{

    if (!translationFile)

        return false;

    if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))

        return false;

    QCoreApplicationPrivate *d = self->d_func();

    if (d->translators.removeAll(translationFile)) {

#ifndef QT_NO_QOBJECT

        if (!self->closingDown()) {

            QEvent ev(QEvent::LanguageChange);

            QCoreApplication::sendEvent(self, &ev);

        }

#endif

        return true;

    }

    return false;
}

 

 

 

 

载入文件QTranslator::load;该函数主要功能是将多语言文件载入。

 

 

自动更新的文件

代码需要处理的事件

常见多语言的错误

Tr()函数的使用。

static QString tr(const char *sourceText, const char * = Q_NULLPTR, int = -1)
{
     return QString::fromUtf8(sourceText); 
}

 

QTranslator使用

QString QCoreApplication::translate(const char *context, const char *sourceText,

                                    const char *disambiguation, int n)

{

    Q_UNUSED(context)

    Q_UNUSED(disambiguation)

    QString ret = QString::fromUtf8(sourceText);

    if (n >= 0)

        ret.replace(QLatin1String("%n"), QString::number(n));

    return ret;

}

 

QObject::trUtf8()使用

static QString tr(const char *sourceText, const char * = Q_NULLPTR, int = -1)

        { return QString::fromUtf8(sourceText); }

通过上面查看函数源码可以看出,所有显示翻译的函数最终调用的都是一样的,这几个函数的左右也是只有在安装了翻译文件时候会在返回数据时从翻译文件中获取对应的信息。

  1. 补充:
static inline QString fromUtf8(const char *str, int size = -1)

{

     return fromUtf8_helper(str, (str && size == -1) ? int(strlen(str)) : size);

    }


QString QString::fromUtf8_helper(const char *str, int size)

{

    if (!str)

        return QString();


    Q_ASSERT(size != -1);

    return QUtf8::convertToUnicode(str, size);

}

注意:在开发中.ui文件会为我们生成retranslateUi()函数,在切换语言时候会自动调用,但是开发时候经常会有部分控件是通过代码中创建的,并非使用.ui文件,这样会造成,在切换语言后,有代码中生成的控件是不能够刷新展示新的对应翻译语言的信息的。因此需要手动在代码中去修改。可以参考下面步骤。

  1. 重写virtual void changeEvent(QEvent *event)override;函数
  2. 新增需要处理UI展示的函数。如void RetranslateUi();
  3. changeEvent处理对应的消息QEvent::LanguageChange
void testWnd::changeEvent(QEvent *event)
{
    switch (event->type())
    {
        case QEvent::LanguageChange:
        {
            RetranslateUi();
            break;
        }
        default:
        break;
    }
}

 


开发中遇到的常见错误:

翻译文件检测不到,

翻译文件qm存放的位置不正确导致读取时候没有找到该文件,或者造成同时加载了多个不同语言的qm文件,导致显示存在问题。

错乱使用翻译函数,导致样式显示异常。

该情况主要是部分开发者,不清楚翻译函数是有何中用途,只知道可以解决中文展示的问题,因为UTF-8编码,但是遗漏了使用了该函数造成的随着语言内容会变化的情况导致的问题。比如:有开发者使用setObjectName(tr("测试"));不使用setObjectName(QString::fromUtf8("测试"));导致样式不显示。

翻译内容过于随意,UI展示不够协调美观。

部分提示弹窗,为了能够更清楚的提示客户,翻译冗长,提示语应当精炼,准确的提示用户。

翻译内容不够精炼,导致显示不全。

有些展示内容,不同国家的语言,可能产生的文字长度不一样,导致最初用来展示的位置不能够完全展示信息,影响用户的使用。在现在的开发中使用了tip的方式展示了信息,解决了描述性信息过长造成的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值