Always select the first item in a QListView during a search
-
Hi,
From the looks of it, you do not take into account the empty selection case.
-
@Gabber said in Always select the first item in a QListView during a search:
selected.indexes().first();
if(selected.indexes().isEmpy()) { // no selection at all } else { QModelIndex index = selected.indexes().first(); }
-
Something is still strange, maybe someone can give me a hint. In my MainWindow I have a QStackWidget with 3 QListViews. The three QListViews are selected via a QComboBox. I connect it in my mainwindow.cpp via:
connect(ui->modelSelection, QOverload<int>::of(&QComboBox::currentIndexChanged), ui->stackedListViews, &QStackedWidget::setCurrentIndex); connect(ui->searchbar, &QLineEdit::textChanged, this, &MainWindow::handleItemSelection); connect(ui->modelSelection, &QComboBox::currentTextChanged, this, &MainWindow::handleItemSelection); connect(mFungusList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MainWindow::fungusSelectionChanged); connect(mSynonymList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MainWindow::synonymSelectionChanged);
Yesterday I wrote that it works fine with my first QListView (index 0 of the QComboBox). But as soon as it selects the second QListView via the QComboBox, the search works, but it doesn't map me the data via the QDataWidgetMapper (mMapper) anymore. I even created a separate slot.
void MainWindow::synonymSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { QModelIndex selectedIndex; QModelIndex proxyIndex; QModelIndex sourceIndex; if(selected.indexes().isEmpty()){ return; } else { selectedIndex = selected.indexes().first(); } const int id = mSynonymProxyModel->data(selectedIndex.siblingAtColumn(2)).toInt(); qDebug() << id; mFungusProxyModel->setIdFilter(id); mSynonymFilterModel->setIdFilter(id); proxyIndex = mFungusProxyModel->index(0,0); sourceIndex = mFungusProxyModel->mapToSource(proxyIndex); qDebug() << sourceIndex; const QString redlist = mFungusProxyModel->data(proxyIndex.siblingAtColumn(7)).toString(); qDebug() << redlist; if(redlist.isEmpty()) ui->redlist->setCurrentIndex(-1); mMapper->setCurrentModelIndex(sourceIndex); mFungusProxyModel->setIdFilter(-1); }
My complete handleItemSelection method looks like this:
void MainWindow::handleItemSelection(const QString &name) { Q_UNUSED(name); QModelIndex index; if(ui->modelSelection->currentIndex() == Model::Fullnames){ index = mFungusList->model()->index(0,1); mFungusList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } if(ui->modelSelection->currentIndex() == Model::Synonyms){ index = mSynonymList->model()->index(0,1); mSynonymList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } if(ui->modelSelection->currentIndex() == Model::GermanNames){ index = mGermanNameList->model()->index(0,0); mGermanNameList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } }
When I switch to synonyms in my QComboBox and select an entry via mouse click from the QListView it works as expected, when I try to select an entry via the search it does not recognize the data for me. My proxyIndex is then always QModelIndex(-1,-1,0x0,QObject(0x0)).
I have no idea what could be wrong. Does anyone have a tip for me again?
-
@Gabber said in Always select the first item in a QListView during a search:
when I try to select an entry via the search it does not recognize the data for me. My proxyIndex is then always QModelIndex(-1,-1,0x0,QObject(0x0)).
I'm not sure to understand what " to select an entry via the search" really means.
QModelIndex(-1,-1,0x0,QObject(0x0)).
Obviously, there's no selection, so you have to select one item by code I guess. -
@mpergand said in Always select the first item in a QListView during a search:
I'm not sure to understand what " to select an entry via the search" really means.
I have a QLineEdit that searches my data in my subclass QSortFilterProxyModel (in my case FungusSortFilterProxyModel) via the setNameFilter(QString) function using a Regular Expression. And after each search I want to select the first element in my second QListView (mSynonymList) and map the data via QDataWidgetmapper to the corresponding QLineEdits.
If I click it with the mouse everything works as expected, but if I tell it to select it (see handleItemSelection) unfortunately it doesn't work. But it is not clear to me why not....
I hope I could explain it a little bit...
-
@Gabber
Put a breakpoint at the beginning of handleItemSelection(),
run the debugger and step by step look what happens here. -
I think I have found my error.
//3 QListViews with 3 subclass QSortFilterProxyModel mFungusList->setModel(mFungusProxyModel); mSynonymList->setModel(mSynonymProxyModel); mGermanNameList->setModel(mGermanNameProxyModel);
I already said that I have my 3 QListViews in a QStack widget. If I now search the first ProxyModel (in my case mFungusProxyModel) and have no hit then select the second page of my QStackWidget and search the stored model (in my case mSynonynProxyModel). Since I have the following signal
connect(mSynonymList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MainWindow::synonymSelectionChanged);
it accesses the slot SynonymSelectionChanged and exactly here it uses mFungusProxyModel which is "empty" since no hit was found and therefore I always get an empty QModelIndex.
I simply created a second model in my Constructor of MainWindow.cpp and added the source model twice.
mFungusProxyModel = new FungusSortFilterProxyModel; mFungusFilterModel = new FungusSortFilterProxyModel; // add source Model mFungusProxyModel->setSourceModel(mFungusDataModel); mFungusFilterModel->setSourceModel(mFungusDataModel);
@SGaist @mpergand
Now I just have a question for the experts, can you do something like that or can it cause complications?It is currently working.
-
@Gabber said in Always select the first item in a QListView during a search:
// add source Model
mFungusProxyModel->setSourceModel(mFungusDataModel);
mFungusFilterModel->setSourceModel(mFungusDataModel);Seems strange to me, but maybe i'm wrong - Model-View pattern gives me headache, too complicated for my little brain :)
In one of my app, i'm using a sorting model and i do like this:
historyModel=new HistoryModel(); historySortFilter= new HistorySortFilter(); historySortFilter->setSourceModel(historyModel); tableView->setModel(historySortFilter);
As you can see, i first set the proxy model to the sorting model,
then set the sorting model to the view.Hope this helps.