17

One cell in each row of a QTableWidget contains a combobox

for (each row in table ... ) {
   QComboBox* combo = new QComboBox();      
   table->setCellWidget(row,col,combo);             
   combo->setCurrentIndex(node.type());                 
   connect(combo, SIGNAL(currentIndexChanged(int)),this, SLOT(changed(int)));
   ....
}

In the handler function ::changed(int index) I have

QComboBox* combo=(QComboBox*)table->cellWidget(_row,_col);  
combo->currentIndex()

To get back a copy of the combobox and get the new selection.
But I can't get the row/col.
None of the table cellXXXX signals is emitted when an embedded item is selected or changed and currentRow()/currentColumn() aren't set.

demonplus
  • 5,613
  • 12
  • 49
  • 68

4 Answers4

13

No need for the signal mapper... When the combobox is created you can simply add two custom properties to it:

combo->setProperty("row", (int) nRow);
combo->setProperty("col", (int) nCol);

In the handler function you can get a pointer back to the sender of the signal (your combobox).

Now by asking for the properties you can have your row/col back:

int nRow = sender()->property("row").toInt();
int nCol = sender()->property("col").toInt();
Richy
  • 534
  • 4
  • 13
  • What if some rows are deleted at runtime? How do i update properties of items? – George Jul 24 '19 at 11:33
  • Got an answer for my question in [this thread](https://stackoverflow.com/questions/25385692/how-to-get-many-qcomboboxes-text-from-qtablewidget?rq=1) – George Jul 24 '19 at 12:16
9

Expanding on Troubadour's answer:

Here's a modification of the QSignalMapper documentation to fit your situation:

 QSignalMapper* signalMapper = new QSignalMapper(this);

 for (each row in table) {
     QComboBox* combo = new QComboBox();
     table->setCellWidget(row,col,combo);                         
     combo->setCurrentIndex(node.type()); 
     connect(combo, SIGNAL(currentIndexChanged(int)), signalMapper, SLOT(map()));
     signalMapper->setMapping(combo, QString("%1-%2").arg(row).arg(col));
 }

 connect(signalMapper, SIGNAL(mapped(const QString &)),
         this, SLOT(changed(const QString &)));

In the handler function ::changed(QString position):

 QStringList coordinates = position.split("-");
 int row = coordinates[0].toInt();
 int col = coordinates[1].toInt();
 QComboBox* combo=(QComboBox*)table->cellWidget(row, col);  
 combo->currentIndex()

Note that a QString is a pretty clumsy way to pass this information. A better choice would be a new QModelIndex that you pass, and which the changed function would then delete.

The downside to this solution is that you lose the value that currentIndexChanged emits, but you can query the QComboBox for its index from ::changed.

Community
  • 1
  • 1
Bill
  • 14,257
  • 4
  • 43
  • 55
2

I think you want to take a look at QSignalMapper. This sounds like a typical use case for that class i.e. you have a collection of objects where you hook up to the same signal on each but would like to know which object emitted the signal.

Troubadour
  • 13,334
  • 2
  • 38
  • 57
-1

Just got same problem and this is how I solved. I use QPoint that is a cleaner way to save a x-y value than a QString. Hope this helps.

classConstructor() {
    //some cool stuffs here
    tableVariationItemsSignalMapper = new QSignalMapper(this);
}

void ToolboxFrameClient::myRowAdder(QString price) {
    QLineEdit *lePrice;
    int index;
    //
    index = ui->table->rowCount();
    ui->table->insertRow(index);
    //
    lePrice = new QLineEdit(price);
    connect(lePrice, SIGNAL(editingFinished()), tableVariationItemsSignalMapper, SLOT(map()));
    tableVariationItemsSignalMapper->setMapping(lePrice, (QObject*)(new QPoint(0, index)));
    // final connector to various functions able to catch map
    connect(tableVariationItemsSignalMapper, SIGNAL(mapped(QObject*)),
             this, SLOT(on_tableVariationCellChanged(QObject*)));
}

void ToolboxFrameClient::on_tableVariationCellChanged(QObject* coords) {
    QPoint *cellPosition;
    //
    cellPosition = (QPoint*)coords;
}
Daniele Vrut
  • 2,835
  • 2
  • 22
  • 32
  • I think you have a memory leak with the QPoint objects, why use new ? Also you don't really need the tools QPoint provide in this case so I don't much benefit from using it. – ymoreau Aug 22 '17 at 08:41
  • @ymoreau thank you for pointing this out. A long time has passed since my reply and I can not answer your question. Have a good day. – Daniele Vrut Aug 24 '17 at 10:49