What's the best way to find a ID from one QSortFilterProxyModel in another QSortFilerProxyModel?
-
Thank you for the help and support. It works now after the "invalidateFilter" has been added.But so that I also learn something I would like to try the version of @eyllanesc. For this I used the QAbstractItemModel::match function. The code looks like this:
const int id = mFungusProxyModel->data(index.siblingAtColumn(0)).toInt(); QModelIndexList list = mSynonymProxyModel->match(QModelIndex(),Qt::DisplayRole,id); QStandardItemModel *myModel = new QStandardItemModel; foreach(QModelIndex myIndex, list){ myModel->setData(myIndex, index.data()); } ui->synonymList->setModel(myModel);Since I haven't found anything on how to get from a QModelIndexList back to a Model and display the whole thing in my QListView, I thought I'd create a QStandardItemModel, iterate over the List and add the data to the Model. Unfortunately, I only have an empty QListView. But now I don't know if it's because of my QModelIndexList, because I use an empty QModelIndex() as start index or what the problem could be. For tips I would be very grateful again.
This is my first QT project so I still have a lot to ask and learn.
@Gabber said in What's the best way to find a ID from one QSortFilterProxyModel in another QSortFilerProxyModel?:
myModel->setData(myIndex, index.data());Check
setData()'s return value, it should be false. You can't do this!myIndexis an index intomSynonymProxyModel, you can't use that to index intomyModel!Either you have to use the result of the
match()as indexes intomSynonymProxyModel, or you would have to copy the data into yournew QStandardItemModel. -
@Gabber said in What's the best way to find a ID from one QSortFilterProxyModel in another QSortFilerProxyModel?:
myModel->setData(myIndex, index.data());Check
setData()'s return value, it should be false. You can't do this!myIndexis an index intomSynonymProxyModel, you can't use that to index intomyModel!Either you have to use the result of the
match()as indexes intomSynonymProxyModel, or you would have to copy the data into yournew QStandardItemModel.Okay, I am now ready to get to my names. I'm just not sure how to tell the ProxyModel (in my case mSynonymProxyModel) to show me only the records from the QModelIndexList. Can you please explain this to me?
My code looks like this:
const int id = mFungusProxyModel->data(index.siblingAtColumn(0)).toInt(); QModelIndex mIndex = mSynonymProxyModel->index(0,2); QModelIndexList list = mSynonymProxyModel->match(mIndex,Qt::DisplayRole,id, -1); foreach(QModelIndex myIndex, list){ auto test = myIndex.siblingAtColumn(1).data(); mSynonymProxyModel-> // What to do here, to set only the data from list } -
Call setData with the index you got and whatever data you want to put there.
-
I already tried that, but when I then add the mSynonymProxyModel to the QListView again, all the data from my ProxyModel is displayed and not just the one from the QModelIndexList. Do I need to do anything else? My code looks like this:
foreach(QModelIndex myIndex, list){ auto test = myIndex.siblingAtColumn(1).data(); //only for debuging mSynonymProxyModel->setData(myIndex, myIndex.data()); } ui->synonymList->setModel(mSynonymProxyModel); -
@Gabber
You never really replied to @eyllanesc's suggestion. If all you want is to get the list of indexes in a model for a value you could use that.For mine we are assuming you actually want to filter a model for a particular value in a particular field. You just need to write the desired
filterAcceptsRow()implementation in a subclass, and have the outside world tell it which value you want to filter on. So you will want something like the following (you can tidy it):class SortFilterByIdProxyModel : QSortFilterProxyModel { private: const int idColumnNumber = 0; int idFilterValue = -1; public: void setIdFilterValue(int id) { if (idFilterValue != id) { idFilterValue = id; emit invalidateFilter(); } } bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override { Q_UNUSED(source_parent); // only tree models use parents, not flat models int id = sourceModel()->index(source_row, idColumnNumber).data().toInt(); // get the ID column's value in the source model's source row return (id == idFilterValue); // row accepted iff its id is the desired idFilterValue } } // Outside world sortFilterByIdProxyModel->setIdFilterValue(valueDesiredFromOtherModel);@JonB said in What's the best way to find a ID from one QSortFilterProxyModel in another QSortFilerProxyModel?:
@Gabber
You never really replied to @eyllanesc's suggestion. If all you want is to get the list of indexes in a model for a value you could use that.
For mine we are assuming you actually want to filter a model for a particular value in a particular fieldIt seems to me using
match()is not what you are looking to do here. Given that you do want to filter, and you had that way working earlier, I don't think you're pursuing anything useful. -
This post is deleted!
-
@JonB
Your code works very well, thank you! I have one more question though: Is there a nicer way to filter by a specific ID or output all records? My code for this looks like this. Of course I always have to setFilterId(-1) which I don't like so much.void FungusSortFilterProxyModel::setIdFilter(const int &id) { if(mIdFilterValue != id) { mIdFilterValue = id; emit invalidateFilter(); } } bool FungusSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { if(mIdFilterValue == -1){ return true; } else { Q_UNUSED(source_parent); const int id = sourceModel()->index(source_row, mIdColumNumber).data().toInt(); return (id == mIdFilterValue); } } -
@JonB
Your code works very well, thank you! I have one more question though: Is there a nicer way to filter by a specific ID or output all records? My code for this looks like this. Of course I always have to setFilterId(-1) which I don't like so much.void FungusSortFilterProxyModel::setIdFilter(const int &id) { if(mIdFilterValue != id) { mIdFilterValue = id; emit invalidateFilter(); } } bool FungusSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { if(mIdFilterValue == -1){ return true; } else { Q_UNUSED(source_parent); const int id = sourceModel()->index(source_row, mIdColumNumber).data().toInt(); return (id == mIdFilterValue); } }@Gabber said in What's the best way to find a ID from one QSortFilterProxyModel in another QSortFilerProxyModel?:
Is there a nicer way to filter by a specific ID or output all records?
Of course I always have to setFilterId(-1) which I don't like so much.I don't know what you are looking for/what is wrong with what you have/what you would rather have?! What is the objection? If there is a valid
mIdFilterValueyou compare it against each row, but if it is invalid you don't bother and just return true. Seems fine to me? -
I just wanted to know if there is a programming possibility to implement filterAcceptsRow in such a way that all records are always output and only when I call setIdFilter(id), it is filtered by this ID. After that all records should be used again automatically. If this is too complex or not possible then I have to work with setIdFilter(-1).
-
I just wanted to know if there is a programming possibility to implement filterAcceptsRow in such a way that all records are always output and only when I call setIdFilter(id), it is filtered by this ID. After that all records should be used again automatically. If this is too complex or not possible then I have to work with setIdFilter(-1).
@Gabber
That is effectively what it is already doing: setting or not setting filter ID to-1is how to test "only when I call setIdFilter(id), it is filtered by this ID". If you really prefer set/unset a boolean flag and test that before looking at filter ID. You have to store something to indicate whether to apply the ID filter or not, it's up to you how you implement that.If you looked at the inbuilt code for when to apply, say, the regular expression or not, you will presumably find code which tests whether it is set to the empty string or not, and only in the latter case to apply the filter. It's just the same with your ID.
-
Thank you very much. I got it to work the way I wanted it to.