原理:
最简单的方式是用 QTranslator, 然后用 QApplication::installTranslator 来设置。后续想改,移除旧的 translator 然后再挂接新的 translator 。通过查找资料及查看 Qt 文档,发现动态切换语言的方式是 Override QWidget 的QEvent::LanguageChange
* 整个过程是这样的,在QApplication::installTranslator之后,其会发送QEvent::ChangeLanguage这个事件,通过在主窗口中捕捉这个事件,然后在其中决定install哪个Translator,注意,在做完此步之后,需要对所有与语言相关的控件再重新设置一遍即可。
实作:
在写完代码后,需要再写一个特定的 .pro 文件,如果你之前用的就是 qmake 来管理 project, 则不需要做这一步,如果你像我一样用 cmake 来管理 Qt 工程,则需要写一个 .pro 文件,只需要包含需要翻译的文件即可,不需要像使用 qmake 一样写全。用 lupdate 更新源代码,得到 .ts 文件,然后用 qlinguist 加载此 .ts 文件,翻译完后,用lrelease 更新 project 文件,自动生成 .qm 文件。
动态翻译实作
main_widget代码
- #ifndef _MAINWIDGET_H_
- #define _MAINWIDGET_H_
- #include <QWidget>
- #include <QMenuBar>
- #include <QVBoxLayout>
- #include <QAction>
- #include <QLabel>
- #include "TestDialog.h"
- #include <QTranslator>
- class MainWidget : public QWidget
- {
- Q_OBJECT
- public:
- MainWidget(QWidget* parent = 0) : QWidget( parent ) {
- menu_bar_ = new QMenuBar( this );
- file_menu_ = new QMenu( QString( tr( "File" ) ),menu_bar_ );
- change_language_action_ = new QAction( QString( tr( "Change Language" ) ),file_menu_ );
- change_language_action_->setCheckable(true);
- change_language_action_->setChecked(false);
- connect( change_language_action_,SIGNAL( triggered( ) ) ,this,SLOT( slot_change_language( ) ) );
- file_menu_->addAction( change_language_action_ );
- toggle_test_dialog_action_ = new QAction( QString( tr( "Show Test Dialog" ) ),file_menu_ );
- file_menu_->addAction( toggle_test_dialog_action_ );
- connect( toggle_test_dialog_action_,SIGNAL( triggered( ) ),this,SLOT( slot_show_test_dialog( ) ) );
- menu_bar_->addMenu( file_menu_ );
- layout_ = new QVBoxLayout( this );
- layout_->setMenuBar( menu_bar_ );
- label_ = new QLabel( QString( tr( "This is a test label" ) ),this );
- layout_->addWidget( label_ );
- setLayout( layout_ );
- test_dialog_ = new TestDialog(this);
- }
- virtual ~MainWidget() {
- delete layout_;
- delete label_;
- delete menu_bar_;
- delete test_dialog_;
- }
- protected:
- void changeEvent(QEvent* event) {
- if(event->type() == QEvent::LanguageChange) {
- retranslate();
- test_dialog_->retranslateUi(test_dialog_);
- } else
- QWidget::changeEvent(event);
- }
- public slots:
- void slot_change_language( ){
- if(change_language_action_->isChecked()) { //en
- qApp->removeTranslator(currentTranslator);
- currentTranslator = new QTranslator();
- currentTranslator->load("en.qm");
- qApp->installTranslator(currentTranslator);
- } else { //cn
- currentTranslator = new QTranslator();
- currentTranslator->load("cn.qm");
- qApp->installTranslator(currentTranslator);
- }
- }
- void slot_show_test_dialog( ) {
- test_dialog_->exec();
- }
- private:
- void installTranslator() {
- currentTranslator = new QTranslator();
- currentTranslator->load("en.qm");
- qApp->installTranslator(currentTranslator);
- }
- void retranslate() {
- file_menu_->setTitle(QString(tr("File")));
- change_language_action_->setText(QString(tr("Change Language")));
- toggle_test_dialog_action_->setText(QString(tr("Show Test Dialog")));
- label_->setText(QString(tr("This is a test label")));
- }
- private:
- QMenuBar* menu_bar_;
- QMenu* file_menu_;
- QAction* change_language_action_;
- QAction* toggle_test_dialog_action_;
- QVBoxLayout* layout_;
- QLabel* label_;
- TestDialog* test_dialog_;
- QTranslator* currentTranslator;
- };
- #endif /* _MAINWIDGET_H_ */
- /* MainWidget.h ends here */
主函数
- #include "MainWidget.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication app( argc,argv ) ;
- MainWidget main_widget;
- main_widget.resize( 640,480 );
- main_widget.show( );
- return app.exec( );
- }
- //
- // main.cpp ends here
cmake工程文件CMakeLists.txt
- set(target_name QtDynamicTranslationTest)
- cmake_minimum_required(VERSION 2.6)
- find_package(Qt4 REQUIRED)
- include(${QT_USE_FILE})
- qt4_wrap_cpp(MainWidget_MOC MainWidget.h)
- add_executable(${target_name} main.cpp TestDialog.h MainWidget.h ${MainWidget_MOC})
- target_link_libraries(${target_name} ${QT_LIBRARIES})
另外,还对QDesigner设计的窗口也进行了测试,亦即测试了手写的代码的语言切换与QDesigner创建的控件的语言切换。