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.

    main.qml

    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 === element.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 {
            anchors.top: combo.bottom
            text: 'Add item'
            onClicked: mymodel.new_item()
        }
    
    }
    
    

    mymodel.py

    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)
    
        @pyqtSlot()
        def new_item(self):
            print('Append new item')
            self._items.append(MyItem('new'))
            self.itemsChanged.emit()
    
    

    main.py

    import os
    import sys
    
    from PyQt5 import QtCore, QtQml, QtWidgets
    from mymodel import MyModel, MyItem
    
    osname = os.name.lower()
    sysplatform = sys.platform.lower()
    windows = os.name.lower() == "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)
    engine.quit.connect(app.quit)
    
    # 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)
    component.loadUrl(qmlFile)
    if component.status() != QtQml.QQmlComponent.Ready:
        for error in component.errors():
            print(error.toString())
        sys.exit(-1)
    
    topLevelItem = component.create()
    if not topLevelItem:
        for error in component.errors():
            print(error.toString())
        sys.exit(-1)
    
    # Now run the main loop until the user closes the application
    topLevelItem.show()
    sys.exit(app.exec_())
    
    
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.