5

I have a bunch of QComboBoxes in a table. So that I know which one was triggered I remap the signal to encode the table cell location (as described in Selecting QComboBox in QTableWidget)

(Why Qt doesn't just send the cell activated signal first so you can use the same current row/column mechanism as any other cell edit I don't know.)

But this removes all knowledge of the original sender widget. Calling QComboBox* combo = (QComboBox* )sender() in the slot fails, presumably because sender() is now the QSignalMapper.

I can use the encoded row/column to lookup the QComboBox in the table widget but that seems wrong. Is there a more correct way to do it?

e.g.:

// in table creator
_signalMapper = new QSignalMapper(this);

 // for each cell
    QComboBox* combo = new QComboBox();
    connect(combo, SIGNAL(currentIndexChanged(int)), _signalMapper, SLOT(map()));
    _signalMapper->setMapping(combo, row);

   // and finally       
   connect(_signalMapper, SIGNAL(mapped(int)),this, SLOT(changedType(int)));

 // slot
 void myDlg::changedType(int row)
 {      
        QComboBox* combo = (QComboBox* )sender(); // this doesn't work !!
 }

EDIT: Added for future search: there is a new book "Advanced Qt Programming" by Mark Summerfield that explains how to do this sort of thing.

Community
  • 1
  • 1
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263

2 Answers2

9

Why not connect the QComboBox's signal straight to your slot?

QComboBox *combo = ...
connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(changedType(int)));

And then in your slot you can use the sender() method to retrieve the QComboBox that was changed.

void myDlg::changedType(int row)
{
    QComboBox *combo = qobject_cast<QComboBox *> sender();

    if(combo != 0){
        // rest of code
    }
}

Alternatively, to use the QSignalMapper method you would just need to change your slot to use the mapping you set up:

void myDlg::changedType(int row)
{
    QComboBox *combo = qobject_cast<QComboBox *>(_signalMapper->mapping(row));

    if(combo != 0){
        // rest of code
    }
}        
Kyle Lutz
  • 7,966
  • 2
  • 20
  • 23
  • The second example is how I would recommend doing this. I imagine the mapping functions were included in the QSignalMapper class for cases just like this one. – Caleb Huitt - cjhuitt Dec 11 '09 at 16:42
  • 1 - Because then I can get a pointer to the actual combobox - but I don't know which table cell it was in, so I don't know which record to change. – Martin Beckett Dec 11 '09 at 16:55
0

I don't know exact answer, but maybe you should use: QComboBox* combo = qobject_cast(sender()) instead of QComboBox* combo = (QComboBox* )sender(). Someting like this:


 QObject* obj = sender();
 QComboBox* combo = qobject_cast<QComboBox*>(obj);
 if(combo)
 {
  doSomethingWithCombo(combo);
 }
 else
 {
  // obj is not QComboBox instance
 }

But maybe QSignalMapper really substitutes itself instead of real sender...

cybevnm
  • 2,586
  • 4
  • 30
  • 33