Qt——Windows+Qt实现国际化(多语言)

2 篇文章 0 订阅
本文详细介绍了如何在Qt应用中利用QTranslator模块实现多语言支持,包括将文本用tr()包裹,创建自定义的CLinguist类以封装翻译功能,通过用户选择或Windows默认语言自动切换翻译。同时,讲解了如何使用Windows API获取用户默认语言,并给出了部分源码实现。此外,还展示了如何使用Qt Linguist工具生成qm文件进行翻译。
摘要由CSDN通过智能技术生成

作者:小 琛
欢迎转载,请标明出处

需求分析

在Windows下,根据Windows操作系统当前的默认语言匹配对应语音包,实现国际化

Qt中的QTranslator模块

QTranslator,头文件<qtranslator.h>

源码:

class Q_CORE_EXPORT QTranslator : public QObject
{
    Q_OBJECT
public:
    explicit QTranslator(QObject *parent = nullptr);
    ~QTranslator();

    virtual QString translate(const char *context, const char *sourceText,
                              const char *disambiguation = nullptr, int n = -1) const;

    virtual bool isEmpty() const;

    QString language() const;
    QString filePath() const;

    bool load(const QString & filename,
              const QString & directory = QString(),
              const QString & search_delimiters = QString(),
              const QString & suffix = QString());
    bool load(const QLocale & locale,
              const QString & filename,
              const QString & prefix = QString(),
              const QString & directory = QString(),
              const QString & suffix = QString());
    bool load(const uchar *data, int len, const QString &directory = QString());

private:
    Q_DISABLE_COPY(QTranslator)
    Q_DECLARE_PRIVATE(QTranslator)
};

源码中实现了常用的一些内容,比如加载qm文件的接口load,这里不做具体讲述,实际使用的时候查阅即可

.qm:该文件是使用Qt语言家翻译后得到的文件

具体操作流程

这里直接上干货,究竟如何实现多语言。

  1. 将代码中所有文本内容用tr()包裹
    在这里插入图片描述
  2. 自定义一个CLinguist类,继承QObject即可。根据个人需要进行封装,例如,为了在每个窗口都可以使用,我将它封装为单例。
enum Language {
	zh_cn,
	en_us,
	undefined
};
class CLinguist :public QObject {
	Q_OBJECT
private:
	CLinguist();

public:
	void changeLanguage(Language lan);
	static CLinguist* getLinguistInstance();

private:
	static CLinguist* m_pLinguist;
	QTranslator* m_pTrans;
	Language m_currentLanguage = Language::undefined;

signals:
	void languageChaned();
};
  • 类内成员包括QTranslator的指针,后续的操作均使用这个类成员
  • m_currentLanguage 来记录当前语言,这里采用枚举的方式,我实现了英语和中文
  • languageChaned()是一个信号,在语言改变时触发,其它界面绑定这个信号即可
enum Language {
	zh_cn,
	en_us,
	undefined
};

类的实现

#include "Linguist.h"
#include <qcoreapplication.h>

CLinguist* CLinguist::m_pLinguist = nullptr;
CLinguist::CLinguist() {
	m_pTrans = new QTranslator;
}

CLinguist* CLinguist::getLinguistInstance() {
	if (nullptr == m_pLinguist) {
		m_pLinguist = new CLinguist;
	}
	return m_pLinguist;
}

void CLinguist::changeLanguage(Language lan) {
	if (lan == this->m_currentLanguage || lan == Language::undefined) {
		return;
	}
	bool ret = false;
	switch (lan) {
	case zh_cn:
		if (nullptr != m_pTrans) {
			qApp->removeTranslator(m_pTrans);
		}
		ret = m_pTrans->load(":/file/file/Translation_zh.qm");
		if (ret) {
			bool install = qApp->installTranslator(m_pTrans);
			if (install == false) {
				MyLogger::Log::error("install translator error");
			}
		} else {
			MyLogger::Log::error("load translation file error");
		}
		break;
	case en_us:
		if (nullptr != m_pTrans) {
			qApp->removeTranslator(m_pTrans);
		}
		ret = m_pTrans->load(":/file/file/Translation_en.qm");
		if (ret) {
			bool install = qApp->installTranslator(m_pTrans);
			if (install == false) {
				MyLogger::Log::error("install translator error");
			}
		} else {
			MyLogger::Log::error("load translation file error");
		}
		break;
	default:
		break;
	}
	if (ret) {
		this->m_currentLanguage = lan;
		emit languageChaned();
	}
}


  1. 将该窗口内所有的设置文本类内容,封装成一个槽函数,在类的构造函数中,将该槽函数和languageChaned()绑定
    在这里插入图片描述

  2. 在工程的翻译文件下添加->Qt->Translation File->选择自己的语言
    在这里插入图片描述
    随后,右击该文件,lupdate lrelease
    在这里插入图片描述
    打开拓展->Qt vs Tools->Launch Qt Linguist
    在这里插入图片描述
    文件->打开刚刚新建的ts文件,对文本进行翻译->文件 发布
    即可得到想要的qm文件
    在这里插入图片描述
    在这里插入图片描述
    一定要注意,这里的qm文件路径,要和CLinguist::changeLanguage中加载的路径对应,否则加载失败是不能翻译的

  3. 我们来简单测试一下,页面上加一个comboBox,让用户可以自主选择语言。这里控件的代码就不贴了,具体根据自己情况而定,仅贴切换使用的槽函数

void Uninstall::onChangeLanguage(int index) {
	CLinguist* lin = CLinguist::getLinguistInstance();
	switch (index) {
	case 0:
		lin->changeLanguage(Language::zh_cn); break;
	case 1:
		lin->changeLanguage(Language::en_us); break;
	default:
		break;
	}
}
  1. 在main中设置一下初始语言
CLinguist* lin = CLinguist::getLinguistInstance();
lin->changeLanguage(Language::zh_cn);

大功告成:
在这里插入图片描述
在这里插入图片描述

Windows下语言类接口

前面实现的功能,做到了根据用户选择实时切换,那么设置初始的默认语言就更简单了,只需要判断当前操作系统语言是什么,调用封装好的接口,加载就行了,唯一要讲述的,是Windows操作系统下的语言类API

推荐使用unsigned short GetUserDefaultUILanguage();
返回值对应不同的语言,下面是常用的语言标准,直接用16进制判断就可以,当然也可以宏定义一下
/*
{0x0804, “CN”, “zh”, “zh_CN”},//中国
{0x0409, “US”, “en”, “en_US”},//美国
{0x0412, “KR”, “ko”, “ko_KR”},//韩国
{0x0411, “JP”, “ja”, “ja_JP”},//日本
{0x0421, “ID”, “en”, “en_ID”},//印度尼西亚
{0x0407, “DE”, “de”, “de_DE”},//德国
{0x040c, “FR”, “fr”, “fr_Fr”},//法国
{0x0410, “IT”, “it”, “it_IT”},//意大利
{0x0416, “BR”, “pt”, “pt_BR”},//葡萄牙
{0x0c0a, “ES”, “es”, “es_Es”},//西班牙
{0x0419, “RU”, “ru”, “ru_RU”},//俄国
{0x041f, “TR”, “tr”, “tr_TR”},//土耳其
{0x042a, “VI”, “vi”, “vi_VI”},//越南
{0x041e, “TH”, “en”, “en_TH”},//泰国
{0x0809, “GB”, “en”, “en_US”},//英国
*/
在这里插入图片描述

CLinguist* lin = CLinguist::getLinguistInstance();
		unsigned short type = GetUserDefaultUILanguage();
		if (type == zh_CN) {
			lin->changeLanguage(Language::zh_cn);

		} else {
			lin->changeLanguage(Language::en_us);
		}

部分源码

注意:里面的Log.h是我自己的日志系统,写代码注意保留日志,使用删除即可

CLinguist.h

#pragma once

#include <QObject>
#include <qtranslator.h>
#include "Log.h"

enum Language {
	zh_cn,
	en_us,
	undefined
};
#define zh_CN 0x0804 
#define zh_Us 0x0809

/*
		{0x0804, "CN", "zh", "zh_CN"},//中国
		{0x0409, "US", "en", "en_US"},//美国
		{0x0412, "KR", "ko", "ko_KR"},//韩国
		{0x0411, "JP", "ja", "ja_JP"},//日本
		{0x0421, "ID", "en", "en_ID"},//印度尼西亚
		{0x0407, "DE", "de", "de_DE"},//德国
		{0x040c, "FR", "fr", "fr_Fr"},//法国
		{0x0410, "IT", "it", "it_IT"},//意大利
		{0x0416, "BR", "pt", "pt_BR"},//葡萄牙
		{0x0c0a, "ES", "es", "es_Es"},//西班牙
		{0x0419, "RU", "ru", "ru_RU"},//俄国
		{0x041f, "TR", "tr", "tr_TR"},//土耳其
		{0x042a, "VI", "vi", "vi_VI"},//越南
		{0x041e, "TH", "en", "en_TH"},//泰国
		{0x0809, "GB", "en", "en_US"},//英国
*/

class CLinguist :public QObject {
	Q_OBJECT
private:
	CLinguist();

public:
	void changeLanguage(Language lan);
	static CLinguist* getLinguistInstance();

private:
	static CLinguist* m_pLinguist;
	QTranslator* m_pTrans;
	Language m_currentLanguage = Language::undefined;

signals:
	void languageChaned();
};
CLinguist.cpp
```cpp
#include "Linguist.h"
#include <qcoreapplication.h>

CLinguist* CLinguist::m_pLinguist = nullptr;
CLinguist::CLinguist() {
	m_pTrans = new QTranslator;
}

CLinguist* CLinguist::getLinguistInstance() {
	if (nullptr == m_pLinguist) {
		m_pLinguist = new CLinguist;
	}
	return m_pLinguist;
}

void CLinguist::changeLanguage(Language lan) {
	if (lan == this->m_currentLanguage || lan == Language::undefined) {
		return;
	}
	bool ret = false;
	switch (lan) {
	case zh_cn:
		if (nullptr != m_pTrans) {
			qApp->removeTranslator(m_pTrans);
		}
		ret = m_pTrans->load(":/file/file/Translation_zh.qm");
		if (ret) {
			bool install = qApp->installTranslator(m_pTrans);
			if (install == false) {
				MyLogger::Log::error("install translator error");
			}
		} else {
			MyLogger::Log::error("load translation file error");
		}
		break;
	case en_us:
		if (nullptr != m_pTrans) {
			qApp->removeTranslator(m_pTrans);
		}
		ret = m_pTrans->load(":/file/file/Translation_en.qm");
		if (ret) {
			bool install = qApp->installTranslator(m_pTrans);
			if (install == false) {
				MyLogger::Log::error("install translator error");
			}
		} else {
			MyLogger::Log::error("load translation file error");
		}
		break;
	default:
		break;
	}
	if (ret) {
		this->m_currentLanguage = lan;
		emit languageChaned();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值