tags:

views:

444

answers:

2

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 http://stackoverflow.com/questions/1332110/selecting-qcombobox-in-qtablewidget)

(Why Qt doesn't just send the cell activated signal first so you can use the same currentRow/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 Tablewidget but that seems wrong.
Is there a more correct way to do it?

eg

// 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:

A: 

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...

vnm
IIRC qobject_cast does the same thing as a regular cast, it just has a few internal checks.
Martin Beckett
At least, this cast will return 0, if there are type mismatch (specified type != requested type)
vnm
+5  A: 

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
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
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
2 - I think the second one is what I wanted thank you
Martin Beckett
+1 because of qobject_cast
elcuco