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

Slot not working with QAbstractListModel in Qml



  • Hi,
    I have a ItemModelclass inherited from QAbstractListModel with the following method :

    @Slot()
    def bla(self):
       print('bla')
    

    the class is added via qmlRegisterType.

    Inside a ListView :

    model: ItemModel {}
    
    // then in delegate
    Button {
    onClicked: model.bla()
    }
    

    CLicking the button returns in the console :
    TypeError: Property 'bla' of object QQmlDMAAbstractItemModelData(0x2cba320) is not a function

    QAbstractListModel is inheriting from QObject so I can't the see where I'm wrong.

    thanks for help
    Jimmy


  • Lifetime Qt Champion

    Hi,

    Please post a complete minimal example that reproduces what you are currently getting.



  • import sys
    
    import PySide2
    from PySide2.QtGui import QGuiApplication
    from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
    from PySide2.QtCore import (
        QUrl,
        QAbstractListModel,
    )
    import typing
    from PySide2.QtCore import QObject, Slot, Qt
    
    class ItemModel(QAbstractListModel):
    
        def __init__(self, parent=None):
            self._datas = ['un', 'deux', 'trois']
            super().__init__(parent=parent)
    
    
        def rowCount(self, parent):
            return len(self._datas)
    
        def data(self, index, role):
            if not index.isValid():
                return None
            elif role == Qt.DisplayRole:
                return self._datas[index.row()]
            else:
                return None
    
        @Slot()
        def bla(self):
            print("bla")
    
    if __name__ == "__main__":
        app = QGuiApplication(sys.argv)
        engine = QQmlApplicationEngine()
        qmlRegisterType(ItemModel, "ItemModel", 1, 0, "ItemModel")
    
        engine.load(QUrl("main.qml"))
    
        if not engine.rootObjects():
            sys.exit(-1)
    
        sys.exit(app.exec_())
    
    import QtQuick 2.0
    import QtQuick.Layouts 1.12
    import QtQuick.Controls 2.12
    import ItemModel 1.0
    
    
    ApplicationWindow {
        id: page
        width: 800
        height: 400
        visible: true
    
        ListView {
            id: listView
            height: 200
            width: 150
            model: ItemModel {}
            clip: true
            delegate: Item {
                width: page.width
                height: 50
                RowLayout {
                    Button {
                        text: model.display
                        height: 30
                        onClicked: model.bla()
                    }
    
    
            }
        }
        }
        }
    

    error : file:///xx/xx/xx/xx/xx/xx/main.qml:67: TypeError: Property 'bla' of object QQmlDMAbstractItemModelData(0x2db34b0) is not a function


  • Lifetime Qt Champion

    The way you do it, you are in fact accessing a wrapper class and not your class directly.

    You should rather create an object of your ItemModel type and then access that object when needed. See:

    import QtQuick 2.0
    import QtQuick.Layouts 1.12
    import QtQuick.Controls 2.12
    import ItemModel 1.0
    
    
    ApplicationWindow {
        id: page
        width: 800
        height: 400
        visible: true
    
        ItemModel {
            id: myModel
        }
    
        ListView {
            id: listView
            height: 200
            width: 150
            model: myModel
            clip: true
            delegate: Item {
                width: page.width
                height: 50
                RowLayout {
                    Button {
                        text: model.display
                        height: 30
                        onClicked: myModel.bla()
                    }
                }
            }
        }
    }
    


  • ok great ti works


Log in to reply