Qt-interest Archive, March 2008
QDataWidgetMapper and invalid indexes
Message 1 in thread
Hi,
I have a database aware form, that shows the content of a single row from a
database table in a form. I use QDataWidgetMapper to map a
QSqlRelationalTableModel to the widgets in the form, and have the edit policy
to OnFieldChange. This works fine... for exactly one commit(). After the any
field on the form is changed/tabbed out of, no further changes are committed
to the database. After a lot of debugging, I tracked it down to the fact that
commit() invalidates any QSqlIndex that might be pointing at it,which means
all calls to commit fails in QDataWidgetMapperPrivate::commit(const
WidgetMapper&) because the model's current index is no longer valid.
So I am not sure what to do here. One solution would be to have the
QDataWidgetMapper to reset the current index whenever the closeEditor()
signal is emitted (from QItemDelegate::eventFilter()). This works, but is
hardly elegant! For one thing, the index is reset a lot more than strictly
neccessary. Is this really the way to do it? It seems to me (at least) that
it is quite seldom that you want to have a form where only one field can be
changed, yet this seems the default behaviour.
Advice?
(Using qt 4.3.2. opensource edition on linux(ubuntu), if that matters).
--
[ signature omitted ]
Message 2 in thread
On Tuesday 04 March 2008 21:43:18 Esben Mose Hansen wrote:
> Hi,
>
> I have a database aware form, that shows the content of a single row from a
> database table in a form. I use QDataWidgetMapper to map a
> QSqlRelationalTableModel to the widgets in the form, and have the edit
> policy to OnFieldChange. This works fine... for exactly one commit(). After
> the any field on the form is changed/tabbed out of, no further changes are
> committed to the database. After a lot of debugging, I tracked it down to
> the fact that commit() invalidates any QSqlIndex that might be pointing at
> it,which means all calls to commit fails in
> QDataWidgetMapperPrivate::commit(const WidgetMapper&) because the model's
> current index is no longer valid.
>
> So I am not sure what to do here. One solution would be to have the
> QDataWidgetMapper to reset the current index whenever the closeEditor()
> signal is emitted (from QItemDelegate::eventFilter()). This works, but is
> hardly elegant! For one thing, the index is reset a lot more than strictly
> neccessary. Is this really the way to do it? It seems to me (at least) that
> it is quite seldom that you want to have a form where only one field can be
> changed, yet this seems the default behaviour.
>
> Advice?
>
> (Using qt 4.3.2. opensource edition on linux(ubuntu), if that matters).
Since noone was able to help me, perhaps I should record to any followers my
finding so far:
To make QWidgetMapper work with an QSqlTableModel, you need to avoid using
editpolicy onFieldChange. That editpolicy kindly invalidates every index
whenever anything is submitted. That means that if you call
QWidgetMapper::submit(), only the first widget will be commited, the rest
will fail since the index is now invalid. Nice :o) It's a good thing I had
the source code, many thanks to the trolls for making Qt open source!
Using QWidgetMapper AutoSubmit is still beyond me. It seems to me the row is
never changed now or something like that. But it can work using
OnManualSubmit, if you then connect the mapper->itemDelegate's signal
commitData(QWidget) to a slot that does 2 things in order:
calls the QWidgetMapper->submit(), and then reset the current index. You can
get the current index before calling submit, so you don't have to store it.
I still find it extremely puzzling why this is not the default behaviour, but
at least it works this way.
--
[ signature omitted ]