Qt QSignalMapper излучает сигнал для каждого элемента на карте

У меня есть функция, которая получает QList класса, который я создал. Давайте назовем этот гипотетический класс "Материал". Итак, эта функция получает QList of Stuff

Я перебираю QList и в зависимости от свойств объекта Stuff создаю одно из следующего:

1) QLineEdit

2) QCheckBox

3) QComboBox

Это не настоящий код, но это то, что я по сути делаю:

void MyProgram::update(QList<Stuff> myStuffs)
{
  this->mSignalMapper = new QSignalMapper();

  foreach (Stuff stuff, myStuffs)
  {
    if (stuff.isInt())
    {
      QLineEdit* input = new QLineEdit();
      //There is code here to setup the QLineEdit and fill an initial value
      verticalLayout->addWidget(input); //verticalLayout is QVBoxLayout
      QObject::connect(input, SIGNAL(editingFinished()), this->mSignalMapper, SLOT(map()));
      this->mSignalMapper->setMapping(input, stuff.getMappingId());
      /*
       * NOTE: the stuff.getMappingId() function returns an int that is unique
       * to that stuff object.  I'm 100% sure each stuff object is getting
       * a unique mapping ID */
      QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
    }
    else if (stuff.isBool())
    {
      QCheckBox* input = new QCheckBox();
      //There is code here to setup the QCheckBox and set an initial value
      verticalLayout->addWidget(input);
      QObject::connect(input, SIGNAL(stateChanged(int)), this->mSignalMapper, SLOT(map()));
      this->mSignalMapper->setMapping(input, stuff.getMappingId());
      QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
    }
    else if (stuff.isStringList())
    {
      QComboBox* input = new QComboBox();
      //There is code here to setup the QComboBox and fill in values for the combo box
      verticalLayout->addWidget(input);
      QObject::connect(input, SIGNAL(activated(int)), this->mSignalMapper, SLOT(map()));
      this->mSignalMapper->setMapping(input, stuff.getMappingId());
      QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
    }
  }
}

Проблема заключается в том, что если я запускаю только один из сигналов виджета, либо редактируя QLineEdit, либо устанавливая флажок, либо изменяя значение поля со списком, функция onStuffChanged(int) вызывается N раз, где N = число Отображения mSignalMapper.

Что тут происходит? Если я перебираю и создаю 10 виджетов, щелчок только по одному из 10 виджетов вызывает функцию 10 раз, и каждый из этих 10 раз передает уникальный int, связанный только с 1 объектом, с которым я взаимодействовал. Таким образом, если 1-й из 10 виджетов был флажком с уникальным int ID, равным 27, функция onStuffChanged(int) вызывается 10 раз с параметром 27 каждый раз.

1 ответ

Решение

Проблема в этой строке:

QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));

Вы делаете одно и то же соединение N раз (N = ваш счет "вещи"), поэтому каждый mapped() сигнал запускает onStuffChanged(int) слот N раз также.

Решение: переместите эту строку за пределы цикла, чтобы вызывать только один раз.

Другие вопросы по тегам