Qt World Summit: Register Today!

QML Combobox not updating with dataChanged signal

  • Hi!

    I have a QML Combobox that does not update the current selected value when the model value is changed by another QML component.
    However, if I open the Combobox, I see the element with the updated value. Selecting the same element will not change the current selected to the correct value, but selecting another value, and then jumping back updates the current selected value correctly.

    The signal dataChanged is emitted each time the model data is changed.

    Is there another signal ComboBox listens to when it comes to updating the current selected value?

    I'm using Qt5.3, QtQuick 2.3 and QtQuick.Controls 1.2

    QML Combobox code:

     ComboBox {
            id: myComboBox
            height: 20
            width: 300
            textRole: "nameRole"
            model: myModel

    myModel is defined in c++ like this:

    class MyModel: public QAbstractListModel

    Where the setData function is implemented like:

    bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role)
        if (!index.isValid() || index.row() >= dataList_.count())
            return false;
        switch(role) {
        case NameRole:
            if(dataList_.at(index.row())->->name() != value.toString())
                emit dataChanged(index, index);

    and roleNames:

    QHash<int, QByteArray> MyModel::roleNames() const
        QHash<int, QByteArray> roles;
        roles[NameRole] = "nameRole";

  • @Andreas.S

    Reproduced problem with QStringListModel. When changing element in model, ComboBox is not updated correctly.

    int main(int argc, char** argv)
        QApplication app(argc, argv);
        QQuickView view;
        QStringListModel nameModel(QStringList() << "One" << "Two" << "Three");
        view.rootContext()->setContextProperty("_nameModel", &nameModel);
        QString loc = "qrc:///main.qml";
        return app.exec();

    And QML:

    import QtQuick 2.3
    import QtQuick.Controls 1.2
    Item {
        id: root
        width: 560
        height: 360
        ComboBox {
            id: comboBox
            model: _nameModel
            textRole: "edit"
            id: editNameDelegate
                id: editNameBox
                visible: comboBox.currentIndex===index ? true: false
                color: "transparent"
                Rectangle {
                    id: changeNameBox
                    border.color: "black"
                    height: 30
                    width: 360
                    anchors.top: parent.top
                    anchors.topMargin: 2
                    anchors.left: parent.left
                        text: "Change Name"
                        font.pixelSize: 18
                        anchors.left: parent.left
                        anchors.leftMargin: 8
                        anchors.verticalCenter: parent.verticalCenter
                        border.color: "black"
                        height: 25
                        width: 200
                        anchors.right: parent.right
                        anchors.rightMargin: 5
                        anchors.verticalCenter: parent.verticalCenter
                            anchors.fill: parent
                            anchors.leftMargin: 3
                            id: changeNameInput
                            text: model.edit
                            Keys.onReturnPressed: {
                                model.edit = text
        ListView {
            anchors.top: comboBox.bottom
            height: 30
            width: 500
            id: editNameAList
            model: _nameModel
            delegate: editNameDelegate
            interactive: false

  • Found a workaround:
    Connect a slot that updates the model completely using either beginInsertRows or ResetModel. This should be called each time data that the combobox displays is changed.

Log in to reply