Singal not working correct when filtering in QSortFilterProxyModel
-
Put them in a QStackedWidget or QStackedLayout and switch the one to view based on your combo box selection.
@SGaist said in Singal not working correct when filtering in QSortFilterProxyModel:
Put them in a QStackedWidget
I managed to do that and it works as expected.
@SGaist said in Singal not working correct when filtering in QSortFilterProxyModel:
Get the source index from what was selected and then use QDataWidgetMapper::setCurrentModelIndex.
I'm just not quite sure how you mean that. In my constructor I do this:
secondList = new QListView; thirdList = new QListView; firstList = new QListView; firstList->setModel(mFungusProxyModel); firstList->setModelColumn(1); secondList->setModel(mSynonymProxyModel); secondList->setModelColumn(1); thirdList->setModel(mGermanNameProxyModel); thirdList->setModelColumn(0); ui->stackedWidget->addWidget(firstList); ui->stackedWidget->addWidget(secondList); ui->stackedWidget->addWidget(thirdList); connect(ui->modelSelection, QOverload<int>::of(&QComboBox::activated), ui->stackedWidget, &QStackedWidget::setCurrentIndex); connect(firstList->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::fungusItemChanged); connect(secondList->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::synonymItemChanged);
And my two slot's looks like this:
void MainWindow::fungusItemChanged(const QModelIndex &index) const { const int id = mFungusProxyModel->data(index.siblingAtColumn(Column::Id)).toInt(); const QString redlist = mFungusProxyModel->data(index.siblingAtColumn(Column::Assignment)).toString(); if(redlist.isEmpty()){ ui->redlist->setCurrentIndex(Index::None); } mSynonymFilterModel->setFilterRegularExpression(idFilter(id)); mSynonymFilterModel->setFilterKeyColumn(Column::FungusId); ui->synonymList->setModel(mSynonymFilterModel); ui->synonymList->setModelColumn(Column::Name); mMapper->setCurrentModelIndex(index); //mMapper is QDataWidgetMapper }
void MainWindow::synonymItemChanged(const QModelIndex &index) const { const int id = mSynonymProxyModel->data(index.siblingAtColumn(Column::FungusId)).toInt(); mFungusProxyModel->setFilterRegularExpression(idFilter(id)) ; mFungusProxyModel->setFilterKeyColumn(Column::Id); mSynonymFilterModel->setFilterRegularExpression(idFilter(id)); mSynonymFilterModel->setFilterKeyColumn(Column::FungusId); ui->synonymList->setModel(mSynonymFilterModel); ui->synonymList->setModelColumn(Column::Name); QModelIndex fungusIndex = mFungusProxyModel->index(0,0); const QString redlist = mFungusProxyModel->data(fungusIndex.siblingAtColumn(Column::Assignment)).toString(); if(redlist.isEmpty()){ ui->redlist->setCurrentIndex(Index::None); } mMapper->setCurrentModelIndex(fungusIndex); //mMapper is QDataWidgetMapper }
If I take now for example the secondList (synonym list) and select a synonym I receive the QModelIndex (by the connect it calls me the slot synonymItemChanged(QModelIndex)). But now it is not clear to me, how I should get from this QModelIndex of the mSynonymProxyModel to the one record of the mFungusProxyModel via the QModelIndex. Can you explain this to me?
-
Which model did you set on your mapper ?
-
@SGaist said in Singal not working correct when filtering in QSortFilterProxyModel:
Which model did you set on your mapper ?
mFungusProxyModel. My mapping looks like this:
mFungusProxyModel->setSourceModel(mFungusDataModel); mMapper->setModel(mFungusProxyModel); mMapper->setItemDelegate(new ProxySqlRelationalDelegate(mMapper)); mMapper->addMapping(ui->number, mFungusDataModel->fieldIndex("ID"), "text"); mMapper->addMapping(ui->fullname, mFungusDataModel->fieldIndex("Vollname")); mMapper->addMapping(ui->genus, mFungusDataModel->fieldIndex("Gattung")); mMapper->addMapping(ui->kind, mFungusDataModel->fieldIndex("Art")); mMapper->addMapping(ui->family, mFungusDataModel->fieldIndex("Familie")); mMapper->addMapping(ui->order, mFungusDataModel->fieldIndex("Ordnung")); mMapper->addMapping(ui->notes, mFungusDataModel->fieldIndex("Anmerkung")); mMapper->addMapping(ui->redlist, mFungusDataModel->fieldIndex("Zuordnung"));
-
@Gabber said in Singal not working correct when filtering in QSortFilterProxyModel:
mFungusDataModel
Your mapper should rather be set on that model so it has all data available.
Then you essentially get the source index from your fungus proxy. For the homonyms, since they are on top of a different model, get the ID and then find the index in mFungusDataModel.
-
@Gabber said in Singal not working correct when filtering in QSortFilterProxyModel:
mFungusDataModel
Your mapper should rather be set on that model so it has all data available.
Then you essentially get the source index from your fungus proxy. For the homonyms, since they are on top of a different model, get the ID and then find the index in mFungusDataModel.
@SGaist
I'm sorry, I can't quite follow you yet. Now I have changed the mapper to mFungusDataModelmMapper->setModel(mFungusDataModel); mMapper->setItemDelegate(new QSqlRelationalDelegate(mMapper));
I also know that with mapFromSource(QModelIndex) I can get the mFungusProxyModel index and with mapToSource(QModelIndex) I can get the index of the mFungusDataModel. So far I have understood that.
My other models are:
mFungusDataModel = mDatabaseManager->fungusData(); //QSqlRelationalTableModel mSynonymDataModel = mDatabaseManager->synonymData(); //QSqlTableModel mGermanNameDataModel = mDatabaseManager->germanNameData(); //QSqlRelationalTableModel mFungusProxyModel->setSourceModel(mFungusDataModel); mSynonymProxyModel->setSourceModel(mSynonymDataModel); mGermanNameProxyModel->setSourceModel(mGermanNameDataModel);
Unfortunately, I do not understand:
@SGaist said in Singal not working correct when filtering in QSortFilterProxyModel:
For the homonyms, since they are on top of a different model, get the ID and then find the index in mFungusDataModel.
Here is how I get the mushroom ID:
const int fungusIdFromSynonymProxy = mSynonymProxyModel->data(index.siblingAtColumn(2)).toInt(); //the id from synonymItemChanged(QModelIndex index) auto modelIndex = mFungusProxyModel->mapToSource(index); const int fungusIdFromFungusProxy = modelIndex.siblingAtColumn(0).data().toInt(); //the id from fungusItemChanged(QModelIndex index)
Now, I have the ID.
@SGaist said in Singal not working correct when filtering in QSortFilterProxyModel:
then find the index in mFungusDataModel.
And that is exactly my problem. How do I do it? Via the function void QSqlTableModel::setFilter(const QString &filter) or whats the best/easiest way?
-
One simple way would be to have a simple proxy model that filters on the ID between the fungus model and the data widget mapper. That way the mapper will only have a single entry to show.
-
One simple way would be to have a simple proxy model that filters on the ID between the fungus model and the data widget mapper. That way the mapper will only have a single entry to show.
@SGaist
I'm starting to get a little confused. I mean that I had that so. Can you show me how you mean that in a code snippet for better understanding? -
You are using twice the same proxy model. What I mean is that your QDataWidgetMapper should not reuse the proxy that is already used to show the data on your other widget.
-
Thank you. It now works as expected. But before I mark the thread as solved I would like to know why you should avoid this?
-
In this case separation of concerns.
You have three views that are filtered in different manners using different proxies. Here you try to reuse the same proxy as one of the views but it might not be filtered that way you need it.
The reference index may come from three different views that don't look the same table so you don't want to take one of these proxies for your mapper.
Keep things cleanly separated.