[Interest] QSqlRelationalModel and QDataWidgetMapper: can items in QComboBox be filtered?
Dmitry Teslenko
dteslenko at gmail.com
Mon Feb 27 08:51:28 CET 2012
> There's nice qt docs example here:
> http://doc.qt.nokia.com/4.7-snapshot/sql-sqlwidgetmapper.html
> demonstrating QSqlRelationalTable, QDataWidgetMapper and QComboBox.
>
> They setup model:
> ...
> query.exec("create table person (id int primary key, "
> "name varchar(20), address varchar(200), typeid int)");
> ...
> query.exec("create table addresstype (id int, description varchar(20))");
> ...
> model = new QSqlRelationalTableModel(this);
> model->setTable("person");
> model->setEditStrategy(QSqlTableModel::OnManualSubmit);
>
> typeIndex = model->fieldIndex("typeid");
>
> model->setRelation(typeIndex,
> QSqlRelation("addresstype", "id", "description"));
> model->select();
>
> and then setup mapper:
> QSqlTableModel *relModel = model->relationModel(typeIndex);
> typeComboBox->setModel(relModel);
> typeComboBox->setModelColumn(relModel->fieldIndex("description"));
>
> mapper = new QDataWidgetMapper(this);
> mapper->setModel(model);
> mapper->setItemDelegate(new QSqlRelationalDelegate(this));
> mapper->addMapping(nameEdit, model->fieldIndex("name"));
> mapper->addMapping(addressEdit, model->fieldIndex("address"));
> mapper->addMapping(typeComboBox, typeIndex);
>
>
> Here's the question: is there a way to filter typeComboBox items while
> editing a record? Say, on button click. User clicks button and theres
> types with some property only in typeComboBox.
> I've tried two things:
> 1) calling setFilter on relModel. This somehow "decouples" combobox
> from mapper and no further updates from typeComboBox pass to model.
> 2) setting typeComboBox::setModel() to relModel wrapped in
> QSortFilterProxyModel. This causes invalid values to assigned. Say,
> I picked second item in filtered list and mapper assigned second
> item in not filtered list to model.
I managed to make it work. My solution is QSortFilterProxyModel and
subclassed QComboBox with new user property and these setter-getter:
QVariant MyComboBox::data() const {
return = model()->data(
model()->index(currentIndex(), <column-with-id-index>),
Qt::EditRole
);
}
void MyComboBox::setData(const QVariant &d) {
QModelIndexList list = model()->match(
model()->index(0, modelColumn()/*note this is column-with-name-index*/),
Qt::EditRole,
d
);
if(list.isEmpty()) {
setCurrentIndex(-1);
} else {
setCurrentIndex(list.at(0).row());
}
}
Here's some more things I don't quite understand.
1) When I call QDataWidgetMapper setCurrentIndex and mapper populates
widgets with data it calls MyComboBox::setData() passing it name from
related table. Why it's name and not index?
2) When I edit form and pick different items from MyComboBox mapper
performs calls to MyComboBox::setData and passes it index values (not
names this time!).
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?
More information about the Interest
mailing list