Qt国际化详细介绍,中文乱码以及解决方案

时间:2022-02-18 21:38:36

Qt国际化的一般步骤

  1. 运行 lupdate,从应用程序的代码中提取所有界面上的可见字符。
          
    这些可见字符必须被 tr() 、QCoreApplication::translate()、Qt_TR_NOOP()、Qt_TRANSLATE_NOOP()等来包裹字符串,具体这些函数或者宏是什么功能,我们后面细说。
     
  2. 使用 Qt Linguist 翻译应用程序。
  3. 运行 lrelease,生成二进制的 .qm 文件,应用程序可以使用 QTranslator 加载这个文件。
 

翻译标志函数和宏

  1. 在类内时,使用tr() 和 Qt_TR_NOOP()
     
    使用 tr() 包裹可见字符,如下代码所示:
    1. QPushButton *button = new QPushButton(this);
    2. button->setText(tr("国际化"));

    上面是将按钮的名称进行国际化,上面也是 tr() 函数的最简单的用法。当然,此种用法还是有其局限性。只有这段代码在类函数里面,并且所属的类继承于 QObject 的时候,才可以使用 tr() 。

     
    如果所属的类不是继承于 QObject,我们可以将上面代码改成下面所示:
    1. QPushButton *button = new QPushButton(this);
    2. button->setText(QObject::tr("国际化"));
    或者使用 Q_DECLARE_TR_FUNCTIONS 将 tr() 函数加入到这个类里,代码如下所示:
    1. class MyClass
    2. {
    3. Q_DECLARE_TR_FUNCTIONS(MyClass)
    4. public:
    5. MyClass();
    6. ...
    7. };

    如果声明的字符串生命资源串和常量,我们就需要使用 QT_TR_NOOP() 和 tr() 配合使用。 示例代码如下所示:

    1. QString FriendlyConversation::greeting(int type)
    2. {
    3. static const char *greeting_strings[] = {
    4. QT_TR_NOOP("Hello"),
    5. QT_TR_NOOP("Goodbye")
    6. };
    7. return tr(greeting_strings[type]);
    8. }

    或者在类内而不在类函数里,代码如下所示:

    1. class MyClass
    2. {
    3. Q_DECLARE_TR_FUNCTIONS(MyClass)
    4. static const char * const ids[] = {
    5. //% "This is the first text."
    6. QT_TR_NOOP("qtn_1st_text"),
    7. //% "This is the second text."
    8. QT_TR_NOOP("qtn_2nd_text"),
    9. 0
    10. };
    11. public:
    12. MyClass();
    13. void addLabels();
    14. ...
    15. };
    16. void MyClass::addLabels()
    17. {
    18. for (int i = 0; ids[i]; ++i)
    19. new QLabel(tr(ids[i]), this);
    20. }
     
  2. 在类外时,使用QCoreApplication::translate() 和 Qt_TRANSLATE_NOOP(),相对于 tr() 函数,translate() 函数的优点:
  • 使用范围更广,tr() 的使用范围在类内使用,translate() 可以在类内也可以在独立的函数中使用,例如:main() 函数。
  • 翻译更精细,因为 translate() 添加了上下文共能,所以他相对于 tr() 可以更精确的进行翻译,例如,translate("MainForm", "draw") 和 translate("SubForm", "draw"); 都是 “draw” 我们可以根据他在不同的窗体上,翻译有所区别。
     
    同样,在 Qt_TRANSLATE_NOOP() 宏中也是相同的用法。