Unsolved How to filter QListView with a costume ItemDelegate and keeps the filtered Items stored in the list
-
I have QListView which a custom delegate for painting the item in the view, and uses QSortFilterProxyModel for filtering, and QStandardItemModel as the model source.
Now the requirements are: after when added for example 1000 items, these items are divided into many types such as error, warn, info, debug and which different contents and also date. When want to filter, for example only shows the error items, then after want to show all the item again, but in this place the filtered out items have been deleted from the list, and no longer available.
So I do not want the items deleted, I want that the items only be hidden from showing, but the items still being present in the list, which when I change the filtering option, it came back.
How to implement such functionality?
The second question is when the filtering option has changed, how to notify the list to refresh again, I did not find any function to call the model or list to do so.
Thanks!!
-
There is one example in qt examples directory. Check it.
-
Hi
It already works that way.
All items stay in QStandardItemModel and QSortFilterProxyModel
will only show the view a subset based on the filer.
If you change the filter, the view should automatically update.
Try to look at
http://doc.qt.io/qt-5/qtwidgets-itemviews-addressbook-example.htmlits filter names.
-
@mrjj Thanks for the reply! Because I am not using the Regex filtering only, so I am unable to update automatically, look to the image below, these are the filtering conditions:
So the sample which is in the Qt documentation is just using Regex, so I cannot call setFilter() function, so in this case, what should I do in case of changing any of the conditions above, the list gets updated.
-
@BAHRAMUDIN-ADIL
Ok, so how are you filtering then ?
Using filterAcceptsRow ? -
@mrjj Yes, I am extending like this:
class MyQSortFilterProxyModel : public QSortFilterProxyModel
and implementing the:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
bool MyQSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); bool result = true; int readState = llv->getReadState(); if(readState > 0) { // if read state was selected bool isNew = index.data(LogListItemDelegate::IsNew).toBool(); result = result&&(readState==1 ? !isNew : isNew); // readState==1 means only read } auto selectedCamera = llv->getSelectedCamera(); if(std::get<0>(selectedCamera) > 0) { // if camera was selected QString title = index.data(LogListItemDelegate::Title).toString(); result = result && title.contains(std::get<1>(selectedCamera)); } int logType = llv->getLOgType(); if(logType > 0) { // if log type was selected int iconType = index.data(LogListItemDelegate::ICON).toInt(); if(logType == 1) { // info result = result && (iconType == 1 || iconType == 9); } else if (logType == 2) { // warn result = result && (iconType == 2 || iconType == 7); } else if (logType == 3) { // error result = result && (iconType == 3 || iconType == 6 || iconType == 8); } } QString searchWord = llv->getSerchWord(); if(!searchWord.isEmpty()) { QString subtitle = index.data(LogListItemDelegate::DT_Subtitle).toString(); result = result && subtitle.contains(searchWord); } return result; }
-
Hi
Ok.
So when you set the new "filter" (new conditions ) , can you try to call
http://doc.qt.io/qt-5/qsortfilterproxymodel.html#invalidateFilter
(in MyQSortFilterProxyModel )
Maybe invalidate() is enough but docs mentions filterAcceptsRow in doc for invalidateFilter -
@mrjj Hmmm, but this function is protected, how to call it to form outside? But I called the invalidate() function, but happens nothing?
-
@BAHRAMUDIN-ADIL
Hi
but dont you call some function in MyQSortFilterProxyModel when user press the OK button to
give it the new parameters ?
Alternatively, just make a new public function that calls invalidateFilter
and then call that from outside. -
@mrjj Yes I know to create a public function by my self and call it from outside and the call this function from inside, I just tried it out, but nothing happens, why it should be like this. In the filterAcceptsRow() I have already checked whether or not to return true, but it still not working as expected?!
-
@BAHRAMUDIN-ADIL
Hmm, that is odd.
I can not guess why it doesn't update. it does for the Qt samples.
Try to use debugger and see what is going on.This example should be close to your code
http://doc.qt.io/qt-5/qtwidgets-itemviews-customsortfiltermodel-example.html
and all it does is to call invalidateFilter();so maybe its the way how you update its Sort parameters ?
-
@mrjj I am also wondering, I debugged it and when calling the function invalidateFilter(), then filterAcceptsRow() did not get called, usually when called any list validate or updated related function, then the list must reload again and the filterAcceptsRow() function must be called in order to get sync.