I’ve got an editable QComboBox with a QCompleter set to a QSortProxyModel, which wraps a QAbstractListModel. If the user types a wholly new string into the box, I want to write that string into the list model so it shows up in future autocompletions. I figure that’s what setInsertPolicy()
is for, but what’s the right QComboBox::InsertPolicy to use when the insert is happening through a QSortProxyModel? Or do I need to implement it another way?
In more detail: the idea is to suggest autocompletion from an alphabetical list of known strings, but also allow the user to enter a new string. New strings then show up in autocompletions in other combo boxes. Standard QCompleter stuff.
My class with the list of known strings inherits QAbstractListModel, but doesn’t store them in alphabetical order. So I have a QSortProxyModel around the QAbstractListModel and the combo boxes look at the proxy. Also standard.
The thing I’m hung up on is, how do I handle inserts? All of the combo boxes’s currentIndex()
es are indexes into the proxy’s sorted list, not the actual underlying list of strings. Do I use InsertPolicy::InsertAlphabetically
or InsertPolicy::InsertAtBottom
? If I use InsertAtBottom
, and I implement insertRows() in my underlying QAbstractListModel inheritor, do I need to call QSortFilterProxy::invalidate() so it knows to reload and re-sort? But then what updates all the combo boxes so they’re pointing at the right index in the newly re-sorted list?
The solution I have now is to use setInsertPolicy( QComboBox::NoInsert )
and then
connect( lineEdit(), &QLineEdit::editingFinished, this, &MyClass::onEditingFinished )
and have onEditingFinished explicitly fish out the underlying source model from the proxy, insert a row into it, and then do
setCurrentIndex( m_proxy_model->mapFromSource( index_in_source_model ) )
which works, but feels like I’m overcomplicating something.
1