Search code examples
comboboxqmlpopupdropdown

QML Combobox popup not updating


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". QML Combobox pupup issue

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?


Solution

  • 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();
        }
    }