Qt多语言切换时,QComboBox引起的一些问题

发布时间 2023-08-09 19:22:30作者: thammer

板子Qt版本为5.9.5
PC开发环境Qt版本为5.12.2

界面有2个QComboBox,其中一个是用于切换语言,最开始使用的是void currentIndexChanged(int index)信号,多语言切换代码大致如下:

//绑定切换信号
connect(ui->cbox_lang, QOverload<int>::of(&QComboBox::currentIndexChanged),this, &FormSystemSetting::onLanguageChanged);

//槽函数
void FormSystemSetting::onLanguageChanged(qint32 index)
{
    bool ret;

    if(index == 0)
    {
        ret = DCSAPP->switchApplicationLanguage(DcsApplication::LANGHAGE_SIMPLE_CN);
    }
    else
    {
        ret = DCSAPP->switchApplicationLanguage(DcsApplication::LANGHAGE_ENGLISH);
    }

    if(ret)
    {
        ui->retranslateUi(this);
        emit translated();
    }
}

//切换语言方法
bool DcsApplication::switchApplicationLanguage(LanguageType type)
{
    if (Q_NULLPTR != _translator)
    {
        qApp->removeTranslator(_translator);
        delete _translator;
        _translator = Q_NULLPTR;
    }


    switch (type)
    {
        case DcsApplication::LANGHAGE_SIMPLE_CN:
        {
            _translator = new QTranslator(qApp);
            if(!_translator->load(":/zh_CN.qm"))
            {
                return false;
            }

            if( qApp->installTranslator(_translator))
            {
                qDebug() << "install translator success";
            }
            break;
        }
        case DcsApplication::LANGHAGE_ENGLISH:
        {
            break;
        }
        default:
            break;
    }

    return true;
}
  • 问题1:PC开发环境没问题,但是到板子上切换语言直接卡死

搜索到的2种解决方案

  • 改用QComboBox::activated信号
    卡死问题解决,但是板子上选择选项后,index不会切过来,需要调用一下setCurrentIndex

  • 依然使用使用QComboBox::currentIndexChanged信号,但是在槽中block一下信号
    问题可以解决

但是同一个界面的另一个ComboBox也使用了QComboBox::currentIndexChanged信号,不会出现卡死。暂时用第一种方法解决了。

  • 问题2:PC开发环境没问题,切换语言时界面上另一个QComboBox的index会变

此时我很怀疑是Qt版本bug引起的问题,因为PC正常,而两者的区别就是Qt版本,而操作另一个QComboBox没问题,所以推测和语言切换相关,再次搜索,加上语言切换关键字,搜到 https://bugreports.qt.io/browse/QTBUG-61778 。原来是老版本Qt调用retranslateUi时会调用QComboBox的clear。我这里切换语言是调用了retranslateUi,这就解释了为啥另一个QComboBox会变的问题,并且语言切换的这个QComboBox的index改变又会触发currentIndexChanged,这样就出现了信号槽的嵌套,导致卡死。

retranslateUi这个函数是由UIC生成,对比PC和板子编译出来的ui头文件,发现板子编译出来的QComboBox部分的代码确实生成了clear操作。所以Qt的补丁也是针对uic这个工具来打的。patch参见 https://codereview.qt-project.org/c/qt/qtbase/+/199198