QSortFilterProxyModel drag/drop issue...
-
Hey
So I'm trying to use the QSortFilterProxyModel system to do some filtering for matching text in my model. Other than that I want to be able to perform drag/drop when view is unfiltered. Now I'm using my own base model derived from QAbstractItemModel and I've re-created the mime/dropMime/canDropMime data functions (not insert/append/in/etc/etc in either of classes) - in my base model - not proxy. But when ever I drop stuff in the proxyView I get incorrect results... There seem to be some kind rule to it.. if I drag/drop on root I get weird stuff, but if I drag/drop within valid parent, it seem to work ?
I also get random qsortfilterproxymodel.cpp line 548 errors... Index from wrong model pased to map to source thini... this appear to happen when I try to re-select dropped items in my treeView, as I have a list of items, and I did index() on them and passes it to itemSelectionRange... I guess index() is wrong index as it comes from base model and not proxy model, so I think I can fix that.
Can any1 help out?
TIA
-
Hi,
You should share your model implementation. It will help people check for your issues.
-
The base model or the proxy one ?
The base model has
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &child) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); QMimeData *mimeData(const QModelIndexList &indexes) const; bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); Qt::ItemFlags flags(const QModelIndex &index) const; GenericTreeNode *getItemFromIndex(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Qt::DropActions supportedDropActions() const; Qt::DropActions supportedDragActions() const; QModelIndex getIndexFromItem(GenericTreeNode *item);
Reimplemented... Most of the functions are mostly thesame or almost thesame as qt implementation here. With exception that I always force to column 0 when drag/drop....
the Proxy only :
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
for now.
Regards
Dariusz -
Since you re-implemented the two models, then both.
-
Hey
So I was just typing over the classes/functions in comment and testing as I go and I think I might have fixed it... it ened up being beginRemoveRows and begineInsertRows calls. It seems that I mostly ignored them in my standalone model implementation due to issues they were generating... but now that I fixed the indexing they appear to work properly... sooo.. yay? Still testing, might be back in a min :- )
-
Okay... it seems to work and I needed to fix my beginInsert/beginRemove rows...
Ok so maybe 1 side question... not to start another proxy topic...
Say I have a data set with categories, each having a list of sub categories... say if I just want to display 1 category + all its sub categories, should I implement it via QSortFilterProxyModel ?
The only way that currently I can think off is to check each row parent, untill I reach the 1st child of root parent and see if that child is visible... seems like a lot of recursive parent checking for it to work tho...
I kinda wish I could just setProxyImagineryRootItem(sourceModel()->rootItem()->child[0]) or something like that so that the view only displays data of that child?
-
@Dariusz
I believe you are saying: you have a number of top-level items, but you only wish to display one of them, downward. I recall this being asked a few weeks ago (in the context of aQFileSystemModel
), and the answer was to use aQSortFilterProxyModel
to filter away all the top-level items except for the one you wish to display. That is assuming you cannot just get away withQAbstractItemView::setRootIndex()
. I may be misunderstanding your question. -
@JonB said in QSortFilterProxyModel drag/drop issue...:
@Dariusz
I believe you are saying: you have a number of top-level items, but you only wish to display one of them, downward. I recall this being asked a few weeks ago (in the context of aQFileSystemModel
), and the answer was to use aQSortFilterProxyModel
to filter away all the top-level items except for the one you wish to display. That is assuming you cannot just get away withQAbstractItemView::setRootIndex()
. I may be misunderstanding your question.That sounds exactly what I want I think!
I have
root >> Category1 >> child1 >> child2 >> child3 >> subCategory1 >> subCategory2 >> etc etc >> Category2 >> Category3 >> Category4
And I'd like to only display Category1 + its children or 2/3/4 or subCategory1/2 etc etc...
I will try the setRootIndex! Sounds like its what I want to do here. However its in treeView... humh... I was hoping I can set it on all views displaying certain proxy model.... will try it out 1st.
Thanks!
-
@Dariusz
You're on your own because I don't really know what I'm talking about :) But forI was hoping I can set it on all views displaying certain proxy model
I think that's is indeed where you would stick to my
use a QSortFilterProxyModel to filter away all the top-level items except for the one you wish to display
-
@JonB said in QSortFilterProxyModel drag/drop issue...:
@Dariusz
You're on your own because I don't really know what I'm talking about :) But forI was hoping I can set it on all views displaying certain proxy model
I think that's is indeed where you would stick to my
use a QSortFilterProxyModel to filter away all the top-level items except for the one you wish to display
Hmmm I was trying the setRootIndex but so far no luck... probably due to my subclassing of model...
How can I filter it in QSortModelTho ? The filterAcceptsRow() only give me 1 item at a time, and if a item is child of a child of a child of a category that I want, then I have to filter them all recursively untill I get category parent and then check if its the one I wish to see... Feels like a lot of work for filtering that will get slow with large data sets... I guess the question is, how can I filter an item and show all its children?
Edit, for now I've done it with while loop...but its not too "Pretty" sadly...
-
@Dariusz
This: https://forum.qt.io/topic/100194/how-to-show-root-directory-in-qfilesystemmodel/8
was the post I had vaguely recalled. It was indeedQFileSystemModel
. The OP concluded withi will have to use QSortFilterProxyModel then..
Have a read, I don't know whether it relates to your situation.