0

I have got a problem with multi language qt (change language on the fly). My form have a combobox which should be translated when language changed. When languageChanged, the app call method retranslateUi() to translate item in the combobox. The combobox have slot corresponding for signal currentIndexChanged().

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

But when method retranslateUi() called, I do this:

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

Problem is: each statement in retranslateUi() will emit the signal currentIndexChanged(), then the slot will call again.

How can I avoid that ?

PhiVH
  • 447
  • 1
  • 5
  • 10

3 Answers3

2

Another solution is to temporary block signals for an object:

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);
}

Or since Qt 5.3 use exception safe RAII QSignalBlocker

QSignalBlocker blocker(ui->comboBox);
Jeruntu
  • 178
  • 1
  • 9
1

clear() and insertItems() will trigger the currentIndexchanged(int) SLOT function of combobox as former changes the index to -1 and later will also changes the index as you are inserting items at position 0.

So restrict on_comboBox_currentIndexChanged(int) by using a flag as follows...

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;
}
Mike
  • 53
  • 1
  • 7
ScarCode
  • 3,074
  • 3
  • 19
  • 32
0

Instead of clearing the comboBox you can only change the text of an item via 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));
}

I assume your solution and the answer from ScarCode will lose the current selected item in the comboBox. This solution should not lose it. (Not tested)

Mike
  • 53
  • 1
  • 7