Opening persistent delegate editors with proxy model
Hi all.
I have a QTreeView hooked up with an implementation of QAbstractItemModel, and the view has a custom delegate set up for one of the columns. I've set it up to open these delegate editors persistently in the following way:
1. Model is populated with data. When it encounters a row that needs a delegate, it notifies the owner and passes on the index in question.
2. The owner stores a QPersistentModelIndex with the given index for later use.
3. Once the model is fully populated, it notifies the owner of this. The owner then goes through each stored index and calls openPersistentEditor() on the view for each one.
4. (If the model data is cleared or re-populated from this point, it will call closePersistentEditor() on each index beforehand and clear them.)
This worked seemingly perfectly, until I installed an implementation of QSortFilterProxyModel for filtering purposes. I tried to change the calls to openPersistentEditor() and closePersistentEditor() to first map the index from source, since the view now uses the proxy model instead, but nothing seems to happen. I can still get the editors to open by double-clicking in the cells, but I cannot make them persistent anymore. I've stepped through as much as I can of the Qt function calls to see if anything is obviously wrong without much luck.
Am I missing something here? Or maybe my way of thinking is entirely wrong?
Any help would be greatly appreciated. :)
Regards,
skauert
Re: Opening persistent delegate editors with proxy model
Have you tried mapping the indexes into proxy model indexes before storing them in persistant model indexes?
Cheers,
_
Re: Opening persistent delegate editors with proxy model
Hi anda, thanks for your response. :)
I have indeed tried that. Going down that route causes an assert to fire in QSortFilterProxyModelPrivate::index_to_iterator. The following code sample highlights it.
Code:
inline QHash<QModelIndex, Mapping *>::const_iterator index_to_iterator(
{
Q_ASSERT(proxy_index.isValid());
Q_ASSERT(proxy_index.model() == q_func());
const void *p = proxy_index.internalPointer();
Q_ASSERT(p);
QHash<QModelIndex, Mapping *>::const_iterator it =
static_cast<const Mapping*>(p)->map_iter;
Q_ASSERT(it != source_index_mapping.constEnd()); // <<-- Asserts here.
Q_ASSERT(it.value());
return it;
}
If it is of any help, I've also included the callstack.
Code:
> QtGuid4.
dll!QSortFilterProxyModelPrivate
::index_to_iterator(const QModelIndex & proxy_index
) Line
174 + 0x8 bytes C
++ QtCored4.
dll!QModelIndex::parent() Line
374 + 0x55 bytes C
++ QtGuid4.
dll!QTreeView::updateGeometries() Line
2706 C
++ QtGuid4.
dll!QTreeView::doItemsLayout() Line
2046 C
++ QtGuid4.
dll!QWidget::event(QEvent * event
) Line
8802 + 0x10 bytes C
++ QtGuid4.
dll!QFrame::event(QEvent * e
) Line
538 + 0xc bytes C
++ QtGuid4.
dll!QApplicationPrivate
::notify_helper(QObject * receiver,
QEvent * e
) Line
4538 + 0x11 bytes C
++ QtCored4.
dll!QEventDispatcherWin32
::event(QEvent * e
) Line
1117 + 0x10 bytes C
++ QtGuid4.
dll!QApplicationPrivate
::notify_helper(QObject * receiver,
QEvent * e
) Line
4538 + 0x11 bytes C
++ QtCored4.
dll!QCoreApplicationPrivate
::sendPostedEvents(QObject * receiver,
int event_type, QThreadData
* data
) Line
1481 + 0xd bytes C
++ QtCored4.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp) Line 477 + 0x10 bytes C++
user32.dll!_InternalCallWinProc@20() + 0x23 bytes
Re: Opening persistent delegate editors with proxy model
Hi all.
I've now figured out what I was doing wrong, and I'd like to share with anyone who might've done the same mistake.
It seems that requesting persistent editors from the view between emitting layoutAboutToBeChanged() and layoutChanged() was the cause for this issue. I'm not 100% sure of the details, but I assume there is some sort of index invalidation going on. Moving the openPersistentEditor() call to after emitting layoutChanged() appears to have fixed it.
(Apologies for necro if this sort of delayed follow-up is frowned upon)
Regards,
skauert