Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Accessing role values using an index in a model



  • I have QAbstractListModel object I am working with in my qml Action:

        onTriggered: {
                console.log("TransferRight")
    
                var index = acqparamsmodel.item.currentIndex
                var model = acqparammodelproxy.sourceModel
                var qindex = model.index(index,0)
                console.log(qindex)
                var modulename = model.data(qindex, model.nameRole)
                var name = model.data(qindex, model.moduleNameRole)
                console.log(modulename, name)
            }
    

    I can get the index and I can call the data method. However, I am unsure of how to get the role integer for the call to data. I have used Q_ENUM on the enum with all the roles. There is also a roleNames function that will map the enum values to text names. I have tried calling data() with a the roleNames string instead of an integer and that doesn't work either. Worse comes to worse I could set global properties when a selection is made and fill those with the name and modulename. However, I really would like to know how to do this via that data call. I assume there are default roles like Qt.DisplayRole or some such, but I have custom roles and role indexes.

    How do I get the custom role names/integers in QML?



  • This is very frustrating. When editing the QML I can auto-complete the NameRole and ModuleNameRole on the acq_params object. However, it will not get that value when printing to console:

        onTriggered: {
                console.log("TransferRight")
    
                var index = acqparamsmodel.item.currentIndex
                //var model = acqparammodelproxy.sourceModel
                console.log(acqparammodelproxy.sourceModel)
                console.log(acq_params)
                console.log(acq_params.NameRole)
                console.log(acq_params.ModuleNameRole)
                console.log(AcqParamModel.NameRole)
                console.log(AcqParamModel.ModuleNameRole)
                var model = acqparammodelproxy
                console.log(acqparammodelproxy.NameRole)
                console.log(acqparammodelproxy.ModuleNameRole)
                var qindex = model.index(index,0)
                console.log(qindex)
                var modulename = model.data(qindex, AcqParamModel.NameRole)
                var name = model.data(qindex, AcqParamModel.ModuleNameRole)
                console.log(modulename, name)
            }
    

    Output:

    qml: TransferRight
    qml: AcqParamModel(0x55ef6e768c90)
    qml: AcqParamModel(0x55ef6e768c90)
    qml: undefined
    qml: undefined
    qml: 386
    qml: 391
    qml: undefined
    qml: undefined
    qml: QModelIndex(0,0,0x55ef75001c20,StreamPrinter::AcqParamModelProxy(0x55ef6e85a9b0))
    qml: Position AVC Module
    

    I did go in a define AcqParamModel using:

    qmlRegisterType<AcqParamModel>("XMUIQml", 1, 0, "AcqParamModel");
    

    So I can get the enum values that way. But that means I cannot write generic code that works with multiple model types. I have to know which model type my code is accessing. This is really cumbersome. Maybe just setting properties on selection would be more generic.


  • Qt Champions 2017

    My knowledge of QML is almost non-existent, but can't you register the enum of AcqParamModel with qmlRegisterUncreatableType()? I think this is why it was invented.

    PS: Or registering the enum of the class directly?



  • I decided to go a different all QML route:

                           MouseArea {
                                anchors.fill: parent
                                onClicked: {
                                    delegate.ListView.view.currentIndex = index
                                    delegate.ListView.view.currentName = name
                                    delegate.ListView.view.currentModuleName = modulename
                                }
                            }
    

    This mousearea is inside my view delegate. I just have to make sure there is a selection. The other route via the data method just has too much boilerplate.



  • Apparently you can access currentItem of the model. So if you set properties on that delegate then you can access them through the currentItem interface.


  • Qt Champions 2018

    I've create a small lib related to your problem : https://github.com/oKcerG/QmlModelHelper

    You can query the roleNames of an arbitrary model with model.ModelHelper.roles as a map property or model.ModelHelper.roleForName("roleName") returning an int.
    There's also some convenience data method like model.ModelHelper.data(row, "roleName").


Log in to reply