Problem getting QComboBox from QWidget
-
Hi everyone.
Im having a pretty basic issue, and I cant figure out how to solve it.
In my program, I have a QTableWidget, that contains QComboBoxes. I have no problem placing them on the table, but I havent been able to retrieve the information.This is how I create my QComboBoxes that I later add to the table
QComboBox *Index; Index=new QComboBox; QStringList Names; Names<<"64kbps"<<"32kbps"<<"16kbps"; Index->addItems(Names); //Here I have created the QComboBox, now I place it in a Widget, and I allign it to the center QWidget *Widget=new QWidget; QHBoxLayout *Layout=new QHBoxLayout(Widget); Layout->addWidget(Index); Layout->setAlignment(Qt::AlignCenter); Widget->setLayout(Layout)
So far Ive created a QWidget containing a QComboBox. To add it to my table, I just simply do
ui->tableWidget_DataTs->setCellWidget(0,2,Index);
Now, when Im trying to get the information, the program shuts down. Ive debugged it, and I know exactly in which line I have the problem
QComboBox *DataRate=(QComboBox*) ui->tableWidget_DataTs->cellWidget(0,2); if(DataRate->currentText()=="64Kbps") //ON THIS LINE IT SHUTS DOWN ChangeDataRate(64);
Im having problem when I try to acces the pointer of DataRate, so clearly I havent been able to get it correctly from the QWidget.
Any ideas on how to correctly get the QComboBox from QWidget?
I guess that, when I create the QComboBox, I could save that pointer somewhere in the memory, and then I can easily acces it, but Id like the Table itself to contain all of its members, and not placing them somewhere else and then telling the Table where they are.
Thanks in advance -
Hi,
You must use qobject_cast when dealing with casts not C style. Also, always verify that what you get is what your asked for.
-
Hi, thanks for your answer.
Im getting closer, but it still wont work. Probably not casting the right way (even though I made it exactly as internet example)This is what Im doing
QWidget *Widget=ui->tableWidget_DataTs->cellWidget(1,2); QComboBox *DataRate; DataRate= qobject_cast<QComboBox*>(Widget);
According to the debugger, Right after I do
QComboBox *DataRate;
DataRate is type QComboBox
After i do
DataRate= qobject_cast<QComboBox*>(Widget);
DataRates transforms into type QComboBox* with a NULL value.
What am I missing?
The casts ive tried.
qobject_cast Obtains a QComboBox* with NULL value
dynamic_cast Obtains a QComboBox* with NULL value
static_cast Obtains a QWidget with information on it
reinterpret_cast Obtains a QWidget with information on itNone of those casts would work
-
Did you check what cellWidget(1, 2) returns ? Is it a valid widget ? What should that be ? How did you put the combo box there in the first place ?
-
Yes, it returns a valid Widget.
This is how I place the ComboBox
QComboBox *Index; Index=new QComboBox; QStringList Names; Names<<"64kbps"<<"32kbps"<<"16kbps"; Index->addItems(Names); //Here I have created the QComboBox, now I place it in a Widget, and I allign it to the center QWidget *Widget=new QWidget; QHBoxLayout *Layout=new QHBoxLayout(Widget); Layout->addWidget(Index); Layout->setAlignment(Qt::AlignCenter); Widget->setLayout(Layout) ui->tableWidget_DataTs->setCellWidget(0,2,Widget);
-
So cellWidget doesn't return a combo box, it returns a widget containing a layout containing your combo box
-
@SGaist so, how we can cast it to
QComboBox*
? -
@maratk1n Use http://doc.qt.io/qt-5/qobject.html#children to get children widgets of ui->tableWidget_DataTs->cellWidget(1,2); and go through the children list until you can successfully cast to QComboBox*.
-
@jsulm Thank you! This helped solve my problem.
Create table:
for(int i = 0; i < dataCount; i++){ ui->tableWidget->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch); for (int j = 1; j < rowCount; j++) { QWidget *checkBoxWidget = new QWidget(); QCheckBox *checkBox = new QCheckBox(); QHBoxLayout *layoutCheckBox = new QHBoxLayout(checkBoxWidget); checkBox->setChecked(false); layoutCheckBox->addWidget(checkBox); layoutCheckBox->setAlignment(Qt::AlignCenter); layoutCheckBox->setContentsMargins(0,0,0,0); ui->tableWidget->setCellWidget(j, i, checkBoxWidget); } QComboBox* comboBox = new QComboBox(); comboBox->setEnabled(false); comboBox->addItems(dataTypes); ui->tableWidget->setCellWidget(0, i, comboBox); }
Read checkboxes:
for (int i = 0; i < ui->dataCount->currentIndex(); i++) { QComboBox *dataType = static_cast<QComboBox*>(ui->tableWidget->cellWidget(0, i)); QCheckBox *inversion = static_cast<QCheckBox*>(ui->tableWidget->cellWidget(1, i)->children().last()); QCheckBox *plot = static_cast<QCheckBox*>(ui->tableWidget->cellWidget(2, i)->children().last()); QCheckBox *bitwise = static_cast<QCheckBox*>(ui->tableWidget->cellWidget(3, i)->children().last()); device->setRDataType(str2QVariant(dataType->currentText()), inversion->isChecked()); if (plot->isChecked()) { // plot needed } if (bitwise->isChecked()) { // bit representation needed } }
-
@maratk1n One note: you should ALWAYS check pointers! Else your app will crash if any of them is null or dangling pointer.
QComboBox *dataType = static_cast<QComboBox*>(ui->tableWidget->cellWidget(0, i)); ... if (plot && plot->isChecked()) {
-
@jsulm sure, you are right :)
Withdynamic_cast
I should try catch exceptionbad_cast
with references or check pointer as well as withstatic_cast
. -
With dynamic_cast I should try catch exception bad_cast
?
dynamic_cast<>
returnsnullptr
if not of right type, it does notthrow
? -
Perhaps I incorrectly expressed my thought, but I wanted to say this:
Otherwise, the runtime check fails. If the dynamic_cast is used on pointers, the null pointer value of type new_type is returned. If it was used on references, the exception std::bad_cast is thrown.
-
Beware:
static_cast
doesn't do any checks so unless it was given a null pointer, it will not return a nullptr.