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
-
I am new with QAbstractModel and stuck here. Here is my code:
main.qmlimport 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" } } } } } }# 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. Butcheckedis actually a bool but it says it's None type. I triedconsole.log(checked)it return bool but Idk why this error occur.Thank you
-
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 Trueat the end of it.