PDA

View Full Version : Access QComboBox inside QTableWidget



phil333
22nd February 2017, 12:05
Hi,

I am currently using the QTableWidget, and some of the fields need to have a dropdown menu, so I inserted some QComboBoxes.

QComboBox* myComboBox = new QComboBox();
ui->tableWidget->setCellWidget(0,i,myComboBox);

Now I need to be able to retrieve the QComboBox Index whenever someone changes a dropdown box.


For the normal cells inside my table, I am using:

on_tableWidget_cellChanged(int row, int column)
{
QTableWidgetItem *myItem = ui->tableWidget->item(row,column);
}

But this does not tell me when one of the QComboBoxes is manipulated by the user.
Does anyone know how I can setup a function which is called whenever the user changes one of the QComboBoxes?

Santosh Reddy
22nd February 2017, 13:27
Connect to currentIndexChanged() signal of QComboBox.

phil333
22nd February 2017, 14:38
thank you for your quick reply.

I am still a bit confused as to how to connect this, especially since the number of qComboboxes in my table can change.
I am assuming I will need to use this at some point:


connect(myComboBox,SIGNAL(currentIndexChanged(QStr ing)) ,info,SLOT(setText(QString)) );


Also, for the currentItemChanged, what do i need as function input?

void gepetto2::on_tableWidget_currentItemChanged(QTable WidgetItem *current, QTableWidgetItem *previous)
{
current->currentIndex();
}

Santosh Reddy
22nd February 2017, 16:17
Well, it may not look straight forward, but you could store the item's row and col index in each combo box, and retrieve them back in the connected slot.

Here is an working example. Just show() this widget



class TableWidget : public QTableWidget
{
Q_OBJECT
public:
enum Id
{
Row = Qt::UserRole + 1,
Col
};

explicit TableWidget(QWidget * parent = 0)
: QTableWidget(parent)
{
setRowCount(5);
setColumnCount(2);

for(int row = 0; row < rowCount(); ++row)
{
for(int col = 0; col < columnCount(); ++col)
{
setItem(row, col, new QTableWidgetItem());

if(col == 0)
{
QComboBox * comboBox = new QComboBox();
comboBox->insertItems(0, QString("1,2,3,4,5,6").split(","));
comboBox->setItemData(0, row, Row);
comboBox->setItemData(0, col, Col);
connect(comboBox, SIGNAL(currentIndexChanged(QString)), SLOT(onComboChanged(QString)));

setCellWidget(row, 0, comboBox);
}
}
}

show();
}

private slots:
void onComboChanged(const QString & text)
{
QComboBox * comboBox = dynamic_cast<QComboBox *>(sender());

if(comboBox)
{
int row = comboBox->itemData(0, Row).toInt();
int col = comboBox->itemData(0, Col).toInt();

item(row, col + 1)->setText(text);
}
}
};

phil333
27th February 2017, 17:29
Thank you for your post. I ended up finding a different workaround. Since i only ended up needing the column number, I pass it as setObjectName to the qCombobox, which is somewhat less complicated. ( i know, it's more of a workaround then a solution...


I declare the box as follows before i pass it to the table

QComboBox* myComboBox = new QComboBox(); // making a new dropdown box
myComboBox->setObjectName(QString::number(i)); // pass column number as object name
connect(myComboBox, SIGNAL(currentIndexChanged(QString)), SLOT(onComboChanged(QString)));
ui->tableWidget->setCellWidget(0,i,myComboBox); // put box into table

Then I call the onComboChanged() (based on what you suggested previously)


void gepetto2::onComboChanged(const QString & text)
{
qDebug() << "onComboChanged " << text;
QComboBox * comboBox = dynamic_cast<QComboBox *>(sender()); // load the qcombobox item


if(comboBox)
{
int column = comboBox->objectName().toInt(); // retrieve column number
qDebug() << "Dropdown: cols " << column << " : " << comboBox->currentText() << " index " << comboBox->currentIndex();
}
}