[SOLVED] QCombobox + QSqlQueryModel
-
Hi guys,
I'm making a simple database application and want to do filtering on combo boxes.
I have a products table and a modules table having a foreign key field pointing to products id column; finally I have a features table having a foreign key field pointing to modules id column; nothing fancy:
@
+------------------------+
| Products |
+------------------------+
|id | name | description |
+------------------------++-------------------------------------+
| Modules |
+-------------------------------------+
|id | productsid | name | description |
+-------------------------------------++-------------------------------------+
| Features |
+-------------------------------------+
|id | modulessid | name | description |
+-------------------------------------+@Then I have a form for entering the features. This form has 2 combo boxes, one for products and one for modules and I want to show only the modules that belong to a product.
For this I have database manager class returning QSqlQueryModel pointer for both products and modules:
@QSqlQueryModel* CDatabaseManager::productsQueryModel()
{
if (m_pProductsQueryModel == NULL)
{
m_pProductsQueryModel = new QSqlQueryModel(this);
}m_pProductsQueryModel->setQuery("SELECT * FROM products");
return m_pProductsQueryModel;
}QSqlQueryModel* CDatabaseManager::modulesQueryModel()
{
if (m_pModulesQueryModel == NULL)
{
m_pModulesQueryModel = new QSqlQueryModel(this);
}m_pModulesQueryModel->setQuery("SELECT * FROM modules");
return m_pModulesQueryModel;
}@I set both those pointers to the QComboBox objects and everything displays nicely except that I only want to see the modules assigned to a product.
On the products combox box, I have a slot called when the current index of Products combo box is triggered. I get the selected product ID from the resultset and trigger a signal for the database manager to update the modules query and select only the items having the correct product ID in the second column.
Simpler, in code that gives:
@void AddFeatureDialog::on_productsCombobox_currentIndexChanged(int index)
{
QModelIndex id = ui->productsCombobox->model()->index(index, 0);
m_nProductId = id.data().toInt();
emit currentProductSelChanged(m_nProductId);
}void CDatabaseManager::onCurrentProductSelChanged( int _nProductId )
{
bool bRet = false;
if (m_db.isOpen())
{
QSqlQuery query;
bRet = query.prepare("SELECT * FROM modules WHERE productid=:productid");
query.bindValue(":productid", _nProductId);
m_pModulesQueryModel->setQuery(query);if (bRet) { // How do I update the model } else { QSqlError err = query.lastError(); //... } }
}@
The form is simply a modal dialog:
@void MainWindow::on_action_Feature_triggered()
{
AddFeatureDialog dlg;
dlg.setProductsModel((QAbstractItemModel*)m_pDatabase->productsQueryModel());
dlg.setModulesModel((QAbstractItemModel*)m_pDatabase->modulesQueryModel());connect(&dlg, SIGNAL(currentProductSelChanged(int)), m_pDatabase, SLOT(onCurrentProductSelChanged(int))); if (dlg.exec() == QDialog::Accepted) {}
}@
The problem here is that according to the documentation doing a setQuery() on the model should be enough to update the view. In my case the combox box gets cleared and remains empty. If within the slot I set a original query, the combo box gets empty; if I set the filter query from the form class (which I wouldn't like to do), the combo gets empty too.
What am I doing wrong?
Cheers,
-
Could you also post the section where you populate the combobox?
-
Well that was easy thanks to my colleague =)
In the slot taking care of filtering
@QSqlQuery query;
bRet = query.prepare("SELECT * FROM modules WHERE productid=:productid");
query.bindValue(":productid", _nProductId);
m_pModulesQueryModel->setQuery(query);@becomes:
@QSqlQuery query;
bRet = query.prepare("SELECT * FROM modules WHERE productid=:productid");
query.bindValue(":productid", _nProductId);
query.exec(); // <--------- Add exec or it won't work
m_pModulesQueryModel->setQuery(query);@So what the documentation does not stipulate is that exec must be called prior to setting the query.
Tim, the combox box is automatically populated by the model / view architecture. Practically the only things required are to set a valid query to a QXmlQueryModel object and set that same QXmlQueryModel object to the QComboBox object using setModel.
Cheers,