The issue is when I change the model of QML editable Combobox the popup list doesn't update. Appending and removing items from model does display correctly, but changing existing item only affects model. I've found a similar question and it said that this bug had been fixed, but in Qt6 which I'm using I still have that problem.
ComboBox
{
id: comboBoxID
textRole: text
currentIndex: 0
editable: true
model: ListModel
{
id: listModelID
ListElement {text: "test0"}
ListElement {text: "test1"}
}
onActivated:
{
console.log('onActivated() model.get(',currentIndex,').text:', model.get(currentIndex).text);
}
onAccepted:
{
console.log('onAccepted() editText:', editText);
model.get(currentIndex).text = editText;
// model.remove(currentIndex);
// model.insert(currentIndex, {text: editText})
}
}
So here for example when I change first item to "tes" it changes in model, but in popup list first item is still named "test0". Also when I choose "test0" after edit, Combobox displays me correct "tes".
But if I use .append(), .remove() or .insert() methods popup list updates correctly. So I think that .get() or .set() methods simply don't emit some update signal for popup component, but which one?
The ListModel QML type is essentially a very thin implementation of a QAbstractItemModel, but it is super basic. It does not implement any smart logic for emitting dataChanged
signals when new data is set.
To be honest, for these reasons, I rarely use the ListModel
and nearly always prefer to implement my own custom list model. There's a guide for how to do that.
There is a hack you could use, if you really want to use the out-of-the box QML ListModel
, though. You could manually call the signals on the model, forcing the update to happen. For instance, calling the modelReset
signal will force every binding to the model to re-evaluate:
import QtQuick 2.15
import QtQuick.Controls 2.15
ComboBox {
editable: true
model: ListModel{
ListElement {text: "test0"}
ListElement {text: "test1"}
}
onAccepted: {
model.set(currentIndex, {text: editText});
model.modelReset();
}
}