QT多语言

1. 步骤描述

  1. 将代码中的字符串使用tr()进行包裹,以便Qt提取字符串用于生成翻译资源文件
  2. 在项目文件中指定需要导出的翻译文件(.ts文件)TRANSLATIONS = english.ts chinese.ts,使用lupdate工具
  3. 使用Linguist程序打开.ts文件,将字符串翻译为目标语言
  4. 使用lrelease工具将翻译好的翻译文件,发布为.qm文件,可以直接在Linguist工具中点击发布
  5. 在程序中通过QTranslator加载不同的.qm文件,实现不同语言的切换

2. tr() 函数使用

用tr()包装过的字符串,可以被Qt自动提取到翻译文件中。

2.1 tr()函数调用

  1. 在使用了Q_OBJECT宏定义的类或QObject的子类中,都可以直接使用,否则需要使用QObject::tr()调用
  2. 或在类定义中用 Q_DECLARE_TR_FUNCTIONS宏把tr()函数添加到类中,之后就可以直接调用了

2.2 tr()函数的注意事项

  • 尽量使用常量字符串,不要使用字符串变量,否则将不能被正确提取
    char* errorStr = "不能删除记录";
    QString str2 = tr(errorStr);
    
  • 若要在tr()函数中使用字符串变量,需要在定义字符串的地方用Qt_TR_NOOP()宏进行标记,这在使用字符串数组时比较有用
  • tr()不能使用拼接的动态的字符串,正确用法如下:
    tr("第%1行").arg(current.row());
    
  • 为了避免在程序中遗漏对某个字符串进行tr()包装,可以在配置文件中添加DEFINES+=Qt_NO_CAST_FROM_ASCII,来避免这种错误,
    这样编译时会禁止const char隐式转换为QString,强制每个字符串必须使用tr()或QLatin1String
    QLatin1String是一个关于const char
    的封装类

3. 示例

界面如下:
在这里插入图片描述
项目文件如下:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# important !!!
TRANSLATIONS = english.ts chinese.ts

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    language.qrc

生成翻译文件:工具->外部->Linguist->Update Translations,此时在项目目录下会生成english.tschinese.ts两个文件

翻译翻译文件:打开Linguist工具,选择chinese.ts文件,界面如下
在这里插入图片描述
翻译对应的字符串,如下所示:

在这里插入图片描述
发布翻译好的内容:文件->发布,在Linguist工具中操作

将生成的.qm文件添加的项目的资源文件中
编写加载代码:

#include "widget.h"
#include "ui_widget.h"
extern QApplication* pApp;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_comboBox_textActivated(const QString &arg1)
{
    Q_UNUSED(arg1);
    if(ui->comboBox->currentIndex()==0){
        translator.load(":/english");

    }else if(ui->comboBox->currentIndex()==1){
        translator.load(":/chinese");
    }else{
        translator.load(":/english");
    }
    qApp->installTranslator(&translator);

}

// 调用installTranslator后,系统会给窗体发送信号将产生了changeEvent槽产生event
void Widget::changeEvent(QEvent* e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            break;
        default:
            break;
    }
    return;
}

ui->retranslateUi(this)的作用就是刷新界面显示新的语言。

注意:
若窗口是由代码实现的,则需要专门设计一个retranslateUi()函数,这样做会麻烦,特别是当窗口过多时。所以大部分软件在切换完语言后需要重启生效,因为窗口创建时会自动调用retranslateUi()函数。

4. 参考

Qt 5.9 C++ 开发指南 16.1 多语言界面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您在使用Qt语言功能时发现子界面的其他QWidget不能及时更新,可能是因为这些QWidget没有正确连接到语言环境信号。在Qt中,当语言环境发生变化时,您需要手动更新所有的QWidget以显示正确的文本。要实现这一点,您可以使用Qt语言环境类 `QLocale`,并将其与`QTranslator`一起使用。 在您的程序中,您需要创建一个单例对象,用于管理语言环境,并在语言环境发生变化时发出信号。然后,您需要将这个信号连接到每个QWidget的`retranslateUi`槽,以便在语言环境发生变化时更新UI。最后,您需要使用`QTranslator`将翻译文件加载到程序中。 以下是一些示例代码,演示如何在Qt中实现这一点: ```c++ // 在单例类中定义语言环境信号 class LanguageManager : public QObject { Q_OBJECT public: static LanguageManager* instance(); signals: void languageChanged(); private: LanguageManager(); QLocale m_currentLocale; }; // 在MainWindow中连接信号和槽 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); LanguageManager* manager = LanguageManager::instance(); connect(manager, &LanguageManager::languageChanged, ui->widget1, &QWidget::retranslateUi); connect(manager, &LanguageManager::languageChanged, ui->widget2, &QWidget::retranslateUi); // 更多连接操作... // 加载翻译文件 QTranslator translator; translator.load("myapp_zh_CN.qm"); qApp->installTranslator(&translator); } // 在单例类中实现语言环境变化的方法 void LanguageManager::setLanguage(const QLocale& locale) { m_currentLocale = locale; emit languageChanged(); } ``` 您可以根据您的具体情况进行修改,但是这个示例代码应该能够帮助您解决问题。如果您还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值