[Qt-interest] if i use QAbstractItemModel::beginMoveRows willselection track moved rows?
Stephen Kelly
steveire at gmail.com
Wed Jun 15 13:34:42 CEST 2011
On Wed, Jun 15, 2011 at 9:06 AM, Ross Bencina
<rossb-lists at audiomulch.com> wrote:
> Stephen Kelly wrote:
>>
>> Ross Bencina wrote:
>>
>>> <snip>
>>>
>>> My problem is that after the drag and drop operation, item A is no longer
>>> selected because I am using emit dataChanged() in my model to invalidate
>>> the rows. Question: if I instead used beginMoveRows()/endMoveRows() then
>>> would the selection update correctly?
>>
>> Yes. The begin/endMoveRows methods update the QPersistentIndexes, which is
>> what the QItemSelection uses to keep the selection up to date. I think I
>> saw
>> that use of dataChanged to handle moves in a book last year, but it is
>> completely wrong for the reason you just hit. In the model, data changes
>> and
>> structural changes are entirely separate.
>
> Thanks for clarifying that Stephen. It makes sense now. (but gee, porting
> from a Widget implementation to a ItemView implementation is like having
> your head turned inside out).
Yep, I think there's definitely room for high level documentation
about concepts in itemviews.
>
>
>>> In any case, the above example is not a contiguous move since
>>> source={1,2,3,4} and destination={4,1,2,3}. How can I deal with this? or
>>> should I just hack my model to directly modify the selection after a
>>> drag-and-drop operation?
>>
>> if (!beginMoveRows(0, 0, QModelIndex(), 4, QModelIndex()))
>> return; // Invalid move attempted.
>>
>> Node *n = myVector.takeFirst();
>> myVector.append(n);
>>
>> endMoveRows();
>
>
> Hmm, well those parameters to beginMoveRows() don't look quite right to me.
> The docs say:
> bool QAbstractItemModel::beginMoveRows ( const QModelIndex & sourceParent,
> int sourceFirst, int sourceLast, const QModelIndex & destinationParent, int
> destinationChild )
Right. I guess I didn't look at the docs :).
should be:
if (!beginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 4))
return; // Invalid move attempted.
>
> I remain unconvinced that beginMoveRows/endMoveRows can actually do what I
> asked since the beginMoveRows docs seems to imply that it is used for moving
> a contiguous selection from one place in the model to another only.
Indeed it is for contiguous selections. If you have non-contiguous
selections you can break them up into non-contiguous ones. See the
implementation here for example where I create multiple command
objects in the non-contiguous case and then execute them (they notify
the move internally):
https://projects.kde.org/projects/kde/kdelibs/repository/revisions/master/entry/kdeui/tests/proxymodeltestsuite/dynamictreemodel.cpp
>
> What I have worked out in the mean time is:
> emit layoutAboutToBeChanged();
>
> QModelIndexList from, to;
>
> // code to insert the appropriate index mappings into from -> to
>
> changePersistentIndexList( from, to );
>
> emit layoutChanged();
>
> This supports non-contiguous source and/or destination row sets, and seems
> to work correctly (selection is correct after move).
Yes, that's what begin/endMoveRows does too pretty much.
>
> I still don't understand what a persistent index is though.
>
The persistent index corrects 'automatically' when the model structure changes:
#include <QtGui>
int main(int argc, char **argv)
{
QStringListModel model(QStringList() << "Monday"
<< "Tuesday"
<< "Wednesday"
<< "Thursday"
<< "Friday"
);
QModelIndex nonPersistent = model.index(2, 0);
qDebug() << "The index is " << nonPersistent
<< ", the data is " << nonPersistent.data();
QPersistentModelIndex persistentIndex(nonPersistent);
qDebug() << "Removing a row";
model.removeRow(0);
qDebug() << "Persistent: " << persistentIndex << persistentIndex.data();
qDebug() << "Non-Persistent: " << nonPersistent << nonPersistent.data();
}
$ ./stringmodel
The index is QModelIndex(2,0,0x0,QStringListModel(0xbfae4404) ) ,
the data is QVariant(QString, "Wednesday")
Removing a row
Persistent: QModelIndex(1,0,0x0,QStringListModel(0xbfae4404) )
QVariant(QString, "Wednesday")
Non-Persistent: QModelIndex(2,0,0x0,QStringListModel(0xbfae4404) )
QVariant(QString, "Thursday")
More information about the Qt-interest-old
mailing list