Important: Please read the Qt Code of Conduct -

How to set currentIndex in ComboBox

  • Hi,
    I have a hard time understanding the concept of the ComboBox. I can set the model to a custom QQmListProperty and setting the textRole. And I also can set the currentIndex to e.g. a number to select the right element. But what I really want is the ComboBox to automatically calculate it's index through a short Javascript function. This function e.g. searches through the model until it finds a match.
    This works as long as the model does not change. After I append a new item to the model, the new list is loaded but the currentIndex is reset to 0. How would I also make it reload the new index? Thanks for any help I really appreciate it!

    Appended is my implementation with PyQt but I doubt this matters from a pure C++ implementation.


    import QtQuick 2.2
    import QtQuick.Layouts 1.1
    import QtQuick.Controls 1.2
    import QtQuick.Dialogs 1.2
    import MyModel 1.0
    import MyItem 1.0
    ApplicationWindow {
        function getCurrentIndex(list, element) {
            if (list && element) {
                for (var i = 0; i < list.length; i++) {
                    if (list[i].name === {
                        console.log('Found item at pos: ' + i)
                        return i
            return -1
        id: mainWindow
        width: 800; height: 600
        color: "gray"
        MyModel {
          id: mymodel
        ComboBox {
            id: combo
            width: parent.width
            currentIndex: getCurrentIndex(mymodel.items, mymodel.item)
            model: mymodel.items
            textRole: 'name'
        Button {
            text: 'Add item'
            onClicked: mymodel.new_item()

    from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
    from PyQt5.QtQml import QQmlListProperty
    class MyItem(QObject):
        nameChanged = pyqtSignal()
        def __init__(self, name, parent=None):
            QObject.__init__(self, parent)
            self._name = name
        @pyqtProperty('QString', notify=nameChanged)
        def name(self):
            return self._name
    class MyModel(QObject):
        itemChanged = pyqtSignal()
        itemsChanged = pyqtSignal()
        def __init__(self, parent=None):
            QObject.__init__(self, parent)
            self._items = [MyItem('one'), MyItem('two'), MyItem('three')]
            self._item = self._items[1]
        @pyqtProperty(MyItem, notify=itemChanged)
        def item(self):
            return self._item
        @pyqtProperty(QQmlListProperty, notify=itemsChanged)
        def items(self):
            print('Query for items')
            return QQmlListProperty(MyItem, self, self._items)
        def new_item(self):
            print('Append new item')

    import os
    import sys
    from PyQt5 import QtCore, QtQml, QtWidgets
    from mymodel import MyModel, MyItem
    osname =
    sysplatform = sys.platform.lower()
    windows = == "nt" and sysplatform.startswith("win")
    # PyQt class name, QML URI, major version, minor version, QML type name
    QtQml.qmlRegisterType(MyModel, 'MyModel', 1, 0, 'MyModel')
    QtQml.qmlRegisterType(MyItem, 'MyItem', 1, 0, 'MyItem')
    app = QtWidgets.QApplication(sys.argv)
    # Create the QML engine
    engine = QtQml.QQmlEngine(app)
    # Load the main.qml file and create the toplevel component
    component = QtQml.QQmlComponent(engine)
    currentFilePath = os.path.dirname(os.path.abspath(__file__))
    mainFilepath = os.path.join(currentFilePath, "main.qml")
    if windows:
        mainFilepath = mainFilepath.replace('\\', '/')
    qmlFile = QtCore.QUrl("file:///" + mainFilepath)
    if component.status() != QtQml.QQmlComponent.Ready:
        for error in component.errors():
    topLevelItem = component.create()
    if not topLevelItem:
        for error in component.errors():
    # Now run the main loop until the user closes the application

Log in to reply