[Solved] -SqlRelation in Widgets, is possible?- (Actually, find index in QComboBox based on model data)
-
Hi,
I need to make QDialogs to edit different types of SqlRecords. For instance, a QDialog to edit Customer records and another to edit User records.
The QDialog should have a method load(int id) to fetch the record from the database.
There are relational fields, for instance, city_id which should relate to the table cities. I want this field to be editable via QComboBox. Is there a way to do this? The QComboBox should show the list of city names but save the id of the city instead. (That, I know a way) But also, when fetching a new record, should take the city_id and select the corresponding city name. (That, I do not know)
So I'm thinking there MUST be an easy way to do this I'm not aware of.. Right?
-
What view? I don't really need a Relational Table Model, I something more like a Relational Record.
The closest aproach I could find is using a QDataWidgetMapper, but that only works with a QSqlTableModel, not with QSqlRecords (at least i don't know how -- that would solve everything). I don't have a QSqlTableModel because I only need to edit ONE record which has to be loaded by its id. So I have a QSqlQuery like this:
@
int customerId = 123; // just an example. id will be provided by the user.
QSqlQuery q;
q.prepare("SELECT * FROM customer WHERE id = :id");
q.bindValue(":id", customerId);
q.exec();
q.first();
QSqlRecord rec = q.record();
@
The Dialog provides QWidgets to edit every relevant field of the record. (Mostly QLineEdits)
That record has a city_id field. Which is of course a foreign key referencing the table cities.
I need a QComboBox to work as a QSqlRelationalDelegate, so the user can edit the city_id field by selecting the city name. How can I achieve this? -
If you do it all by hand:
- load the cities data in a separate query (select name, id from cities)
- put all the data in a combo box (text = name, userdata = id)
- load your customer data
- get the cities index in the combobox by findData with search for UserRole
- set the combobox to the index found
-
[quote author="Volker" date="1294852654"]If you do it all by hand:
- load the cities data in a separate query (select name, id from cities)
- put all the data in a combo box (text = name, userdata = id)
- load your customer data
- get the cities index in the combobox by findData with search for UserRole
- set the combobox to the index found
[/quote]
That's it! findData. That could work. Thank's Volker!
Just a question though. I'm filling the QComboBox with setModel and setModelColumn. Is there a way to "setModelColumnForData" ? Or I need to make a loop and set it manually?
-
Ok nevermind, it's not possible. Read a few mailing list about this. It's not possible to properly work with QComboBox and models.
-
I almost wish QComboBox had a method like this:
@
int QComboBox::findData (int modelColumn, const QVariant & data, int role = Qt::UserRole, Qt::MatchFlags flags = static_castQt::MatchFlags ( Qt::MatchExactly | Qt::MatchCaseSensitive ) ) const@
That would make things much simplier when working with models.Instead, the solution is to search the model like this:
@ // find row
QModelIndexList matches = ui->condAlIVAComboBox->model()->match(
ui->condAlIVAComboBox->model()->index(0,0),
Qt::EditRole,
r.value("customer_vat_id"),
1,
Qt::MatchExactly
);
if (matches.isEmpty()) {
// handle error
} else {
ui->condAlIVAComboBox->setCurrentIndex(matches.first().row());
}
@Just posting to give closure to the thread. It's now Solved. Thanks Volker for pointing me in the right way.
-