Search code examples
c++qtdynamicsignals-slots

qt creating dynamic object and assigning a different function to the same signal


So in my program I'm generating dynamically some QCheckBox, the number depends from the result of the query and next to each QCheckBox I want to have a QLineEdit which would only be shown when the QCheckBox is checked so how can I link it.

So far, I only have something like that and I don't how to do that without having a vector of pointers of everything created dynamically (like that vector<vector<QObject*> > objets;):

sondage_page2::sondage_page2(QWidget *parent) :
QWidget(parent),
ui(new Ui::sondage_page2)
{
    // ...
    if(query.exec())
    {
        if(query.size()>0)
        {
            while(query.next())
            {
                QCheckBox* check=new QCheckBox(query.value("Marque").toString());
                ui->gridLayout->addWidget(check,row,0,Qt::AlignHCenter);

                vector<QObject*> temp;
                temp.push_back(check);
                objets.push_back(temp);

                QObject::connect(check,SIGNAL(stateChanged(int)),this,SLOT(checked(int)));
            }
            // ...
        }
    }
}

void sondage_page2::checked(int state)
{
    // très broken
    if(state==2) // checked
    {
        QLineEdit* edit=new QLineEdit();
        objets.at(objets.size()-1).push_back(edit);
        ui->gridLayout->addWidget(edit,row-1,1,Qt::AlignHCenter);
    }
    else
    {
       delete objets.at(row-1).at(1);
       objets.at(row-1).pop_back();
    }
}

EDIT : Basically, I want to have a QLineEdit to be shown (or created) on the same line as my QCheckBox when the QCheckBox is created, and with the QObject::connect function I can only link objets to the same function, how can I have this working?


Solution

  • The following is no turn-key solution. It just shows a possible way how you could do it. Most likely not the best possible solution.

    You could use a

    QMap<QCheckBox*,QLineEdit*>

    to associate your QCheckBox with your QLineEdit.

    In sondage_page2::sondage_page2:

    QCheckBox* check=new QCheckBox(query.value("Marque").toString());
    ...add to grid...
    map[check] = nullptr;
    connect(.....)
    

    In sondage_page2::checked:

    QCheckBox *check = qobject_cast<QCheckBox *>(sender());
    if(check){
      if(state == 2){
         QLineEdit* edit=new QLineEdit();
         map[check] = edit;
         ...enter edit in gridlayout...
      }else{
         ...remove from layout....
         map[check].take()->deleteLater() // delete the QLineEdit;
         edit->deleteLater();
      }
    }else{
      // should not be possible... I think
    }
    

    These snippets should exactly do what the code you outlined above intends to do... as far as I understood. Not all possibly necessary sanity checks in place, e.g. is check really in map?