Qt Многоязычный QCombobox

У меня проблема с мультиязычностью qt (изменение языка на лету). В моей форме есть поле со списком, которое должно быть переведено при смене языка. Когда languageChanged, метод вызова приложения retranslateUi() для перевода элемента в поле со списком. В поле со списком есть слот, соответствующий сигналу currentIndexChanged().

void on_comboBox_currentIndexChanged(int index)
{
//do something
}

Но когда вызывается метод retranslateUi(), я делаю так:

void retranslateUi()
{
ui->comboBox->clear();
ui->comboBox->insertItems(0, QStringList()
         << QApplication::translate("SettingDialog", "English", 0, QApplication::UnicodeUTF8)
         << QApplication::translate("SettingDialog", "French", 0, QApplication::UnicodeUTF8)
        );
}

Проблема в том, что каждый оператор в retranslateUi() будет выдавать сигнал currentIndexChanged(), после чего слот будет вызываться снова.

Как я могу этого избежать?


person PhiVH    schedule 31.07.2012    source источник


Ответы (3)


clear() и insertItems() вызовут функцию currentIndexchanged(int) SLOT поля со списком, поскольку первая изменяет индекс на -1, а позже также изменит индекс, когда вы вставляете элементы в позицию 0.

Поэтому ограничьте on_comboBox_currentIndexChanged(int), используя флаг следующим образом...

void on_comboBox_currentIndexChanged(int index)
{
if(!retranslateFlag)
//do something
}


void retranslateUi()
{
retranslateFlag = true;
ui->comboBox->clear();
ui->comboBox->insertItems(0, QStringList()
     << QApplication::translate("SettingDialog", "English", 0, QApplication::UnicodeUTF8)
     << QApplication::translate("SettingDialog", "French", 0, QApplication::UnicodeUTF8)
    );
retranslateFlag = false;
}
person ScarCode    schedule 31.07.2012

Другим решением является временная блокировка сигналов для объекта:

void retranslateUi()
{
    auto isBlocked = ui->comboBox->blockSignals(true);
    ui->comboBox->clear();
    ui->comboBox->insertItems(0, QStringList()
     << QApplication::translate("SettingDialog", "English", 0, QApplication::UnicodeUTF8)
     << QApplication::translate("SettingDialog", "French", 0, QApplication::UnicodeUTF8);
    );
    ui->comboBox->blockSignals(isBlocked);
}

Или, поскольку Qt 5.3 использует безопасный для исключений RAII QSignalBlocker

QSignalBlocker blocker(ui->comboBox);
person Jeruntu    schedule 09.03.2016

Вместо очистки comboBox вы можете изменить текст элемента только через void QComboBox::setItemText(int index, const QString &text)

void retranslateUi()
{
    ui->comboBox->setItemText(0, QApplication::translate("SettingDialog", "English", 0, QApplication::UnicodeUTF8));
    ui->comboBox->setItemText(1, QApplication::translate("SettingDialog", "French", 0, QApplication::UnicodeUTF8));
}

Я предполагаю, что ваше решение и ответ от ScarCode потеряют текущий выбранный элемент в поле со списком. Это решение не должно его терять. (Не испытано)

person Mike    schedule 07.08.2018