Qt之国际化

基本概念:

       Qt提供了一种自己的国际化方案,而不是采用INI配置文件的方式。对于绝大多数的应用程序,在刚启动时,需要加载默认的语言(或最后一次设置的语言)。在使用的过程中,我们也不需要重启应用程序而实现语言的动态切换。

       

      

   要进行多语言的切换,需要执行以下步骤:

  • 对用户可见的文本信息全部使用tr()进行封装。
  • 提供用户可以用来切换语言的一种方法。
  • 对于每一个窗口部件或者对话框,重写changEvent事件,当事件类型为QEvent::LanguageChange时,翻译文本进行重新调用。

   模仿一去二三里大佬写的demo,主界面,设置界面,设置界面可根据选择不同的语言下拉选项实现语言的动态切换。

   设置界面:setting_dialog.h

#pragma once

#include <QDialog>
#include <QLabel>
#include <QComboBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QVariant>
typedef enum{
	UI_ZH,
	UI_EN
}LANGUAGE;
Q_DECLARE_METATYPE(LANGUAGE)
class setting_dialog : public QDialog
{
	Q_OBJECT

public:
	setting_dialog(QWidget *parent=0);
	~setting_dialog();

	void loadConfig();

protected:
	void changeEvent(QEvent *event);

private slots:
    void onIndexChange();

signals:
	void switchLanuage(LANGUAGE language);

private:
	void translateUI();

private:
	QLabel *language_label;
	QComboBox *language_combo_box;
	QLabel *info_label;
};

 设置界面:setting_dialog.cpp

#include "setting_dialog.h"
#include"util.h"
#include<QEvent>
setting_dialog::setting_dialog(QWidget *parent)
	: QDialog(parent)
{
	this->setMinimumSize(300,200);
	this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint);

	language_label = new QLabel();
	language_combo_box = new QComboBox();
	info_label = new QLabel();
	//设置组合框的宽度
	language_combo_box->setMaximumWidth(80);
	language_combo_box->addItem("chinese",QVariant::fromValue(UI_ZH));
	language_combo_box->addItem("english",QVariant::fromValue(UI_EN));
	
	QHBoxLayout *language_layout = new QHBoxLayout();
	language_layout->addStretch();
	language_layout->addWidget(language_label);
	language_layout->addWidget(language_combo_box);
	language_layout->addStretch();
	language_layout->setSpacing(5);
	language_layout->setContentsMargins(0, 0, 0, 0);
	
	QVBoxLayout *main_layout = new QVBoxLayout();
	main_layout->addWidget(info_label, 0, Qt::AlignCenter);
	main_layout->addLayout(language_layout);
	main_layout->setSpacing(10);
	main_layout->setContentsMargins(10, 10, 10, 10);

	this->setLayout(main_layout);
	this->translateUI();

	qRegisterMetaType<LANGUAGE>("LANGUAGE");

	connect(language_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &setting_dialog::onIndexChange);

}

setting_dialog::~setting_dialog()
{
}
void setting_dialog::translateUI()
{
	this->setWindowTitle(tr("setting dialog"));
	info_label->setText(tr("no brothers no programming"));
	language_label->setText(tr("language"));
	language_combo_box->setMaximumWidth(80);
	language_combo_box->setItemText(UI_ZH,tr("chinese"));
	language_combo_box->setItemText(UI_EN, tr("english"));
}
void setting_dialog::onIndexChange()
{
        //保存当前项的内容
        LANGUAGE language = language_combo_box->currentData().value<LANGUAGE>();

	emit switchLanuage(language);
}


void setting_dialog::loadConfig()
{
	QString language_value;
	QString language_suffix = QString("zh");
	LANGUAGE language = UI_ZH;
	bool is_read = util::readInit(QString("./user.ini"), QString("language"), language_value);
	if (is_read)
	{
		language = (LANGUAGE)language_value.toInt();
		if (language == UI_EN)
		{
			language_suffix = QString("en");
		}
	}

	int count = language_combo_box->count();
	for (int i = 0; i <count; i++)
	{
		if (language == i)
		{
			language_combo_box->setCurrentIndex(language);
			break;
		}
	}
}
void setting_dialog::changeEvent(QEvent *event)
{
	switch (event->type())
	{
	case QEvent::LanguageChange:
		translateUI();
		break;
	default:
		QDialog::changeEvent(event);
	}
}

主界面:main_widget.h

#pragma once

#include <QWidget>
#include <QTranslator>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "setting_dialog.h"
#include "util.h"
class main_widget : public QWidget
{
	Q_OBJECT

public:
	main_widget(QWidget *parent=0);
	~main_widget();

	void setLanguage(LANGUAGE current_language);
	void setTranslator(QTranslator *translator);

private:
	QLabel *welcome_label;
	QPushButton *setting_button;
	QPushButton *ok_button;
	QPushButton  *cancel_button;
	setting_dialog *setting_dialo;

	LANGUAGE current_language;
	QTranslator *translator;
private:
	void translateUI();          //主界面UI

protected:
	void changeEvent(QEvent *event);

private slots:
   void showSetting();
   void switchLanguage(LANGUAGE language);
   void cancle();

};

主界面:main_widget.cpp

#include "main_widget.h"
#include<QEvent>

#pragma execution_character_set("utf-8")
main_widget::main_widget(QWidget *parent)
	: QWidget(parent)
{
	//窗口大小
	this->setMinimumSize(400,300);

	welcome_label = new QLabel();
	setting_button = new QPushButton();
	ok_button = new QPushButton();
	cancel_button = new QPushButton();
	setting_dialo = new setting_dialog();

	QHBoxLayout *button_layout = new QHBoxLayout();
	button_layout->addStretch();
	button_layout->addWidget(setting_button);
	button_layout->addWidget(ok_button);
	button_layout->addWidget(cancel_button); 

	QVBoxLayout *main_layout = new QVBoxLayout();
	
	//窗口中间
	main_layout->addWidget(welcome_label,0,Qt::AlignCenter);
	main_layout->addLayout(button_layout);
	main_layout->setSpacing(10);
	main_layout->setContentsMargins(10,10,10,10);

	this->setLayout(main_layout);
        translateUI();

	connect(setting_button, &QPushButton::clicked, this, &main_widget::showSetting);
	connect(setting_dialo, &setting_dialog::switchLanuage, this, &main_widget::switchLanguage);
	connect(cancel_button, &QPushButton::clicked, this, &main_widget::cancle);
}

main_widget::~main_widget()
{
}

void main_widget::translateUI()
{
	this->setWindowTitle(tr("main widget"));
	welcome_label->setText(tr("For what it is worth , it is never too late"));
	setting_button->setText(tr("setting"));
	ok_button->setText(tr("ok"));
	cancel_button->setText(tr("cancel"));
}
void main_widget::setLanguage(LANGUAGE current_language)
{
	this ->current_language = current_language;
}
void main_widget::setTranslator(QTranslator *translator)
{
	this->translator = translator;
}
void main_widget::changeEvent(QEvent *event)
{
	switch (event->type())
	{
	case QEvent::LanguageChange:
		translateUI();
		break;
	default:
		QWidget::changeEvent(event);
	}
}
void main_widget::showSetting()
{
	setting_dialo->loadConfig();
	setting_dialo->exec();
}

void main_widget::switchLanguage(LANGUAGE language)
{
	QString language_qm;
	switch (language)
	{
	case UI_ZH:
		language = UI_ZH;
		language_qm = QString(":/qm/main_widget_zh");
		break;

	case UI_EN:
		language = UI_EN;
		language_qm = QString(":/qm/main_widget_en");
		break;

	default:
		language = UI_ZH;
		language_qm = QString(":/qm/main_widget_zh");
	}

	if (current_language != language)
	{
		current_language = language;
		translator->load(language_qm);
		util::writeInit(QString("./user.ini"), QString("language"), QString::number(language, 10));
	}
}
void main_widget::cancle()
{
	this->close();
}

main:

#include <QApplication>
#include <QTranslator>
#include "main_widget.h"
#include"util.h"
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);

	QString language_value;
	//默认为中文
	QString language_suffix = QString("zh");
	LANGUAGE language = UI_ZH;
	
	bool is_read = util::readInit(QString("./user.ini"),QString("language"),language_value);
	if (is_read)
	{
		language = (LANGUAGE)language_value.toInt();
		if (language==UI_EN)
		{
			language_suffix = QString("en");
		}
	}
	QTranslator translator;
	translator.load(QString(":/qm/main_widget_")+language_suffix);
	a.installTranslator(&translator);

	main_widget main_widge;
	main_widge.setTranslator(&translator);
	main_widge.setLanguage(language);
	main_widge.show();

	return a.exec();
}

注:

  • Q_DECLARE_METATYPE:如果要使自定义类型或其他非QMetaType内置类型在QVariant中使用,必须使用该宏 。

  • qRegisterMetaType:如果非QMetaType内置类型要在信号与槽中使用。

流程:

      1.进入main(),首先加载默认的语言(或是最后一次设置的语言),然后显示主界面。

      2.当打开设置界面后,首先加载当前选择的语言,然后通过下拉设置语言选项来进行语言切换(设置界面的switchLanguage信号关联到主界面的switchLanguage槽中),然后将当前的语言进行保存。

      3.语言切换后,首先会进入changeEvent函数,判断当事件类型为QEvent::LanguageChange时,就会执行translateUI函数进行文本重新显示。

本文转自:https://blog.csdn.net/liang19890820/article/details/50276673

猜你喜欢

转载自blog.csdn.net/m0_37806112/article/details/80156817
今日推荐