Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Problem with changing data from the QML to the Python QAbstractModel
Qt 6.12 LTS is out! See what's new in the release blog

Problem with changing data from the QML to the Python QAbstractModel

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 2 Posters 516 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Y Offline
    Y Offline
    yegender
    wrote on last edited by
    #1

    I am new with QAbstractModel and stuck here. Here is my code:
    main.qml

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.5
    import QtQuick.Layouts 1.3
    Window {
        width: 1280
        height: 720
        visible: true
        title: qsTr("Application attempt #51")
        color:"#88000000"
        SwipeView{
            id:mainSwipeView
            x:0
            y:0
            width:parent.width
            height:parent.height
            //Main Download Page
            Component.onCompleted: {
                if (pyModel.rowCount() === 0){
                    currentIndex = 1;
                } else {
                    currentIndex = 0;
                }
            }
            Rectangle {
                color:"#00000000"
                Rectangle{
                    color:"#88000000"
                    width:parent.width
                    height:80
                    x:0
                    y:0
                    Button{
                        x:0
                        y:0
                        height:parent.height
                        width:parent.width/3
                        background:Rectangle{
                            color:"#00000000"
                        }
                        onClicked:{mainSwipeView.currentIndex = 1;}
                        Label{
                            text: "Add"
                            anchors.centerIn: parent
                            font.pixelSize: 20
                            color:"white"
                        }
                    }
                    Button{
                        x:parent.width/3
                        y:0
                        height:parent.height
                        width:parent.width/3
                        Label{
                            text: "Remove"
                            anchors.centerIn: parent
                            font.pixelSize: 20
                            color:"white"
                        }
                        font.pixelSize: 20
                        background:Rectangle{
                            color:"#00000000"
                        }
                        onClicked:{pyModel.removeSelected();}
                    }
                    Button{
                        x:parent.width*2/3
                        font.pixelSize: 20
                        y:0
                        Label{
                            text: "Pause"
                            anchors.centerIn: parent
                            font.pixelSize: 20
                            color:"white"
                        }
                        height:parent.height
                        width:parent.width/3
                        background:Rectangle{
                            color:"#00000000"
                        }
                    }
                }
                ListView{
                    model:pyModel
                    clip:true
                    contentHeight: 100
                    width:parent.width
                    height:parent.height-80
                    y:80
                    x:0
                    delegate: Rectangle{
                        Rectangle{
                            z:-1
                            color:"#aa000000"
                            height:parent.height
                            width:(model.percentage/100)*parent.width
                        }
    
                        color:"#44000000"
                        height:100
                        width:parent.width
                        CheckBox{
                            checked: model.isChecked
                            onClicked: model.isChecked = checked // I guess here is the error
                            x:0
                            y:0
                            width:100
                            height:100
                        }
    
                        Label{
                            text:model.name
                            x:110
                            y:10
                            color:"white"
                            font.pixelSize: 24
                        }
                        Label{
                            text:"Progress: "+String(model.percentage)+"%"
                            x:120
                            font.pixelSize: 17
                            y:(parent.height-20)-height/2
                            color:"white"
                        }
                        Label{
                            text:"Status: "+String(model.status)
                            x:parent.width-(width+20)
                            font.pixelSize: 17
                            y:(parent.height-20)-height/2
                            color:"white"
                        }
                    }
                }
            }
            Rectangle {
                color:"#88000000"
    
                //TopBar
                Rectangle{
                    color:"#88000000"
                    width:parent.width
                    height:80
                    x:0
                    y:0
                    Button{
                        x:0
                        y:0
                        height:parent.height
                        width:parent.width/3
                        background:Rectangle{
                            color:"#00000000"
                        }
                        onClicked:{mainSwipeView.currentIndex = 0;}
                        Label{
                            text: "Show Queue"
                            anchors.centerIn: parent
                            font.pixelSize: 20
                            color:"white"
                        }
                    }
                }
                //MainSection
                Item{
                    y:80
                    x:0
                    width:parent.width
                    height:parent.height-80
                    Label{
                        text:"Hey, Welcome Again"
                        font.pixelSize: 72
                        color:"white"
                        x:parent.width/2-width/2
                        y:linkinputTextBox.y-(height/2+100)
                    }
    
                    TextField{
                        id:linkinputTextBox
                        placeholderText: "Video Link"
                        x:100
                        width:parent.width-410
                        font.pixelSize: 24
                        background: Rectangle{
                            color:"#88000000"
                        }
                        color: "white"
                        y:parent.height/2-height/2
                    }
                    Button{
                        width:200
                        height:linkinputTextBox.height
                        y:parent.height/2-height/2
                        x:parent.width-300
                        Label{
                            text:"Go"
                            color:"white"
                            font.pixelSize: 24
                            anchors.centerIn: parent
                        }
                        background: Rectangle{
                            color:"#88000000"
                        }
                    }
                }
            }
        }
    }
    
    

    main.py

    # This Python file uses the following encoding: utf-8
    import sys
    from pathlib import Path
    
    from PySide2.QtGui import QGuiApplication
    from PySide2.QtQml import QQmlApplicationEngine
    from PySide2.QtCore import QAbstractListModel,QModelIndex,Qt,Slot
    
    class Model(QAbstractListModel):
    
        _col1 = Qt.UserRole + 1
        _col2 = Qt.UserRole + 2
        _col3 = Qt.UserRole + 3
        _col4 = Qt.UserRole + 4
        _col5 = Qt.UserRole + 5
        def __init__(self, parent=None):
            super(Model, self).__init__(parent)
    
            # Each item is a dictionary of key/value pairs
            self.myData = []
        def append(self, item):
            """Append item to end of model"""
            self.beginInsertRows(QModelIndex(),
                                 self.rowCount(),
                                 self.rowCount())
    
            self.myData.append(item)
            self.endInsertRows()
        @Slot(int)
        def remove(self, index):
            self.beginRemoveRows(QModelIndex(),index,index)
            self.myData.pop(index)
            self.endRemoveRows()
        @Slot()
        def removeSelected(self):
            i=0
            while(i != self.rowCount()):
                if self.myData[i]["isChecked"]:
                    self.remove(i)
                else:
                    i+=1
        def data(self, index, role):
            """Return value of item[`index`] of `role`"""
            row = index.row()
            if index.isValid() and 0 <= row < self.rowCount():
                if role == self._col1:
                    return self.myData[row]["name"]
                if role == self._col2:
                    return self.myData[row]["status"]
                if role == self._col3:
                    return self.myData[row]["percentage"]
                if role == self._col4:
                    return self.myData[row]["isChecked"]
                if role == self._col5:
                    return self.myData[row]["uid"]
        def setData(self, index, value, role):
            """Set item[`index`] of `role` to `value`"""
            self.myData[index.row()][role] = value
            self.dataChanged.emit(index, index)
    
        def rowCount(self, parent=QModelIndex()):
            return len(self.myData)
    
        def roleNames(self):
            return {
        self._col1: b"name",
        self._col2: b"status",
        self._col3: b'percentage',
        self._col4: b'isChecked',
        self._col5: b'uid'}
    model = Model()
    model.append({"uid":0,"name":"an","status":"down","percentage":10,"isChecked":False})
    model.append({"uid":1,"name":"an","status":"down","percentage":40,"isChecked":False})
    model.append({"uid":2,"name":"an","status":"down","percentage":20,"isChecked":True})
    model.append({"uid":3,"name":"an","status":"down","percentage":60,"isChecked":False})
    model.append({"uid":4,"name":"an","status":"down","percentage":80,"isChecked":False})
    model.append({"uid":5,"name":"an","status":"down","percentage":90,"isChecked":False})
    model.append({"uid":6,"name":"an","status":"down","percentage":100,"isChecked":False})
    model.append({"uid":7,"name":"an","status":"down","percentage":0,"isChecked":False})
    if __name__ == "__main__":
        app = QGuiApplication(sys.argv)
        engine = QQmlApplicationEngine()
        engine.rootContext().setContextProperty("pyModel", model)
        qml_file = Path(__file__).resolve().parent / "main.qml"
        engine.load(str(qml_file))
        if not engine.rootObjects():
            sys.exit(-1)
        sys.exit(app.exec_())
    
    

    I am getting some error like sys:1: RuntimeWarning: Invalid return value in function QAbstractListModel.setData, expected bool, got NoneType. when I check the checkbox. But checked is actually a bool but it says it's None type. I tried console.log(checked) it return bool but Idk why this error occur.

    Thank you

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      As the error message tells you: your setData method returns None but it should return a Boolean value.

      You just need to add return True at the end of it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt
      • Unsolved