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

介绍Qt国际化的文章不少,但是真正详细介绍的不多。鄙人专门学习了一下Qt的国际化,在此做一点分享。欢迎大家拍砖。


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() 包裹可见字符,如下代码所示:
    QPushButton *button = new QPushButton(this);
    button->setText(tr("国际化"));
    上面是将按钮的名称进行国际化,上面也是 tr() 函数的最简单的用法。当然,此种用法还是有其局限性。只有这段代码在类函数里面,并且所属的类继承于 QObject 的时候,才可以使用 tr() 。

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

    如果声明的字符串 生命资源串和常量,我们就需要使用 QT_TR_NOOP() 和 tr() 配合使用。 示例代码如下所示:
    QString FriendlyConversation::greeting(int type)
    {
        static const char *greeting_strings[] = {
            QT_TR_NOOP("Hello"),
            QT_TR_NOOP("Goodbye")
        };
        return tr(greeting_strings[type]);
    }
    或者 在类内而不在类函数里 ,代码如下所示:
    class MyClass
    {
        Q_DECLARE_TR_FUNCTIONS(MyClass)
        static const char * const ids[] = {
    	//% "This is the first text."
    	QT_TR_NOOP("qtn_1st_text"),
    	//% "This is the second text."
    	QT_TR_NOOP("qtn_2nd_text"),
    	0
        };
    public:
        MyClass();
    	void addLabels();
        ...
    };
    
    void MyClass::addLabels()
    {
        for (int i = 0; ids[i]; ++i)
            new QLabel(tr(ids[i]), this);
    }

  2. 在类外时,使用QCoreApplication::translate() 和 Qt_TRANSLATE_NOOP(),相对于 tr() 函数,translate() 函数的优点:
  • 使用范围更广,tr() 的使用范围在类内使用,translate() 可以在类内也可以在独立的函数中使用,例如:main() 函数。
  • 翻译更精细,因为 translate() 添加了上下文共能,所以他相对于 tr() 可以更精确的进行翻译,例如,translate("MainForm", "draw") 和 translate("SubForm", "draw"); 都是 “draw” 我们可以根据他在不同的窗体上,翻译有所区别。

    同样,在 Qt_TRANSLATE_NOOP() 宏中也是相同的用法。

可见字符为中文,乱码问题


当我们的可见字符为中文的时候,在 Qt Linguist 中汉语显示为乱码,例如,tr("国际化"),在 Qt Linguist 中显示乱码如下图所示。
Qt国际化详细介绍,中文乱码以及解决方案_第1张图片
标红的地方全是乱码,这种乱码只是因为编码方式不对导致。在 Qt Linguist 中所有字符串都是默认的 Latinl 编码,所以导致中文乱码。下面我们就需要对 Qt Linguist 进行更改。

在 Qt Linguist 源码中我们需要更改两处:
  1. messagemodel 单元内的 MessageItem 类,将原来 text()函数 代码:
        QString text() const { return m_message.sourceText(); }
    改为:
        QString text() const
        {
            QString result = m_message.sourceText();
            return QString::fromLocal8Bit(result.toLatin1());
        }
    这样,现在我们的显示就变成了如下图所示。
    Qt国际化详细介绍,中文乱码以及解决方案_第2张图片
    在其他地方乱码,也可以类似的更改。MessageItem 就是他显示的一条需要翻译的记录。

  2. sourcevcodeview 单元内的 SourceCodeView 类,将原来代码:
    void SourceCodeView::showSourceCode(const QString &absFileName, const int lineNum)
    {
        ……
        fileText = QString::fromLatin1(file.readAll());
        ……
    }
    改为:
    void SourceCodeView::showSourceCode(const QString &absFileName, const int lineNum)
    {
        ……
        fileText = QString::fromLocal8Bit(file.readAll());
        ……
    }
    更改完代码后,我们的程序就变成了如下所示。
    Qt国际化详细介绍,中文乱码以及解决方案_第3张图片

仍然存在的问题


在 “短语和猜测” 窗体中不显示,还未查询是什么原因。

你可能感兴趣的:(乱码,解决方案,qt,国际化,QT_TR_NOOP)