I am working in Qt 4.7, and I have a QWidget object in my dialog. I need to go through each of the children and extract the current text into a QStringList. Every other object is a QCheckBox, and the rest are QComboBoxes (I would just need the text portion of both). So far the only way I could think of to do this would be to use the children() function to get them as QObject*'s and cast them, like this:
QStringList textlist;
for(int i = 0; i < ui->myWidget->children().size(); i++)
{
if(i % 2 == 0)
{
QCheckBox *q = (QCheckBox *)ui->myWidget->children().at(i);
textlist.append(q->text());
}
else
{
QComboBox *q = (QComboBox *)ui->myWidget->children().at(i);
textlist.append(q->currentText());
}
}
However, when I try to use this, it builds and compiles fine, but then crashes when it's run. I checked and both classes are subclasses (albeit indirectly through QAbstractButton and QWidget) of QObject, which is the type of the objects in the list ui->myWidget->children(), so I feel like they should be able to cast this way. I haven't worked much with this kind of thing before so I'm not sure if there's a better way to do this. If anyone has any ideas, it would be greatly appreciated. Thanks!
UPDATE: So, I can't get the casting to work this way or with the qobject_cast. I HAVE however discovered that I can go from QObject to QWidget, and I think I should be able to go from QWidget to the needed objects with dynamic_cast, but that doesn't work either. Right now I have this:
QStringList textlist;
for(int i = 0; i < ui->myWidget->children().size(); i++)
{
QWidget *qw = qobject_cast<QWidget*>(ui->myWidget->children().at(i)
if(i % 2 == 0)
{
QComboBox *q = dynamic_cast<QComboBox*>(qw);
if(q)
{
textlist.append(q->text());
}
}
else
{
QCheckBox *q = dynamic_cast<QCheckBox*>(qw);
if(q)
{
textlist.append(q->currentText());
}
}
}
If anyone has any ideas, I'd appreciate the help. Thank you.
UPDATE2: I haven't found much online that helps with this still, so I may as well ask as well, if there is anyway to do this WITHOUT casting, i.e. getting the objects directly from the QWidget in their original type, I would really appreciate that as well. I'm not heartset on my current strategy or anything, it was just the only way I could think to do it - I'll take anything that works at this point.
You should think about using qobject_cast
. After the cast you should also check if the object is valid.
QStringList textlist;
for(int i = 0; i < ui->myWidget->children().size(); i++)
{
if(i % 2 == 0)
{
QCheckBox *q = qobject_cast<QCheckBox*>(ui->myWidget->children().at(i));
if(q)
textlist.append(q->text());
}
else
{
QComboBox *q = qobject_cast<QComboBox*>(ui->myWidget->children().at(i));
if(q)
textlist.append(q->currentText());
}
}
But this still seems like a bad design to me. The widget class that contains the comboboxes and checkboxes should have a function, that goes through the checkboxes and comboboxes and returns a QStringList
. Then you could just call that function.
Here is an example
mywidget.h:
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
QStringList getComboTextList();
QStringList getCheckBoxTextList();
private:
Ui::MyWidget *ui;
QList<QComboBox*> comboList;
QList<QCheckBox*> checkList;
};
mywidget.cpp:
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
this->setLayout(new QVBoxLayout);
for(int i = 0; i < 5; i++)
{
QCheckBox *checkBox = new QCheckBox(this);
this->layout()->addWidget(checkBox);
checkBox->setText(QString("Check box #%1").arg(i));
checkList.append(checkBox);
}
for(int i = 0; i < 5; i++)
{
QComboBox *comboBox = new QComboBox(this);
this->layout()->addWidget(comboBox);
comboBox->addItem("Combo box item 1");
comboBox->addItem("Combo box item 2");
comboList.append(comboBox);
}
}
MyWidget::~MyWidget()
{
delete ui;
}
QStringList MyWidget::getComboTextList()
{
QStringList returnList;
for(int i = 0; i < comboList.length(); i++)
{
returnList << comboList[i]->currentText();
}
return returnList;
}
QStringList MyWidget::getCheckBoxTextList()
{
QStringList returnList;
for(int i = 0; i < checkList.length(); i++)
{
returnList << checkList[i]->text();
}
return returnList;
}
Then in your other class you can just call getCheckBoxTextList
or getComboTextList
like this:
QStringList comboTextList = myWidget->getComboBoxList();
QStringList checkTextList = myWidget->getCheckBoxTextList();