[PyQt] PyQt5.8.2 Qml GridView TypeError: unable to convert a Python 'MyListModel' object to a C++ 'QAbstractListModel*' instance
chunyisong at sina.com
chunyisong at sina.com
Mon Apr 3 02:46:03 BST 2017
Hello everyone,
I encountered an “TypeError” that my python subclass listmodel of QAbsctactListModel object can not be recognized as a C++ 'QAbstractListModel*' instance!
In order to simplify the problem, I simplified the project code to a demo attachments and also listed below the contents of the email.
The demo has two python subclass of QAbsctactListModel :RuleModel and RuleGroupModel;RuleModel instance will be a role of RuleGroupModel
to provide rules of a group.I test it with PyQt5.7.1 and PyQt5.8.2 ,both encountered the same Type Error which crashed the app is:
" TypeError: invalid result from RuleGroupModel.data(), unable to convert a Python 'RuleModel' object to a C++ 'QAbstractListModel*' instance ".
But when the count of changing model of Qml GridView "many times" ,the error raised.I am confused thar the error do not occure within a few times such as 5 or more times;
The error will surely occure after more times of rule model change.To reproduce the error I use a Timer in the Test.qml to simulate many times of user actions.
Any advice to the e
Thanks in advance!
The demo code:
#### testmodel.py#######################
#encoding:utf8
'''
file:testmodel.py
'''
# import cgitb
# cgitb.enable()
import sys
from PyQt5.QtCore import QUrl, QAbstractListModel,QModelIndex,pyqtSlot
from PyQt5 import QtQml
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView
class RuleModel(QAbstractListModel):
def __init__(self,name=2,parent=None):
super().__init__(parent)
self._datas = [{"name":"name %s" % k} for k in range(name)]
def setDS(self,ds):
self._datas = ds
def roleNames(self):
return {300:"name".encode()}
def data(self,index,role=500):
return self._datas[index.row()][self.roleNames().get(role).decode()]
def rowCount(self,parent=QModelIndex()):
return len(self._datas)
class RuleGroupModel(QAbstractListModel):
def __init__(self,parent=None):
super().__init__(parent)
self._datas = [{"name":"na1" ,"rulesModel":RuleModel(name=1)},
{"name":"na2" ,"rulesModel":RuleModel(name=2)},
{"name":"na3" ,"rulesModel":RuleModel(name=3)},
{"name":"na4" ,"rulesModel":RuleModel(name=4)}
]
def setDS(self,ds):
self._datas = ds
@pyqtSlot(str,result=int)
def roleValue(self, roleName):
if roleName == 'name':
return 300
elif roleName == 'rulesModel':
return 500
return -1
def roleNames(self):
return {300:"name".encode(),500:"rulesModel".encode()}
def data(self,index,role=500):
return self._datas[index.row()][self.roleNames().get(role).decode()]
def rowCount(self,parent=QModelIndex()):
return len(self._datas)
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = QQuickView()
engine = view.engine()
engine.quit.connect(app.quit)
modelA = RuleGroupModel()
engine.rootContext().setContextProperty('ruleGroupsModel', modelA)
view.setResizeMode(QQuickView.SizeRootObjectToView)
QtQml.qmlRegisterType(RuleGroupModel, 'RuleGroupModel', 1, 0, 'RuleGroupModel')
QtQml.qmlRegisterType(RuleMode
l, 'RuleModel', 1, 0, 'RuleModel')
view.setSource(QUrl('Test.qml'))
view.show()
sys.exit(app.exec_())
#### end of testmodel.py#######################
#### Test.qml #######################
importQtQuick2.7
importQtQuick.Controls2.0
importQtQuick.Layouts1.0
Page{
width:300
height:600
header:ComboBox{
id:groups
currentIndex:-1
displayText:currentIndex==-1?"selectagroup":currentText
model:ruleGroupsModel
textRole:"name"
onCurrentIndexChanged:{
rulesView.model=model.data(model.index(currentIndex,0),
model.roleValue('rulesModel'))
}
}
Timer{
id:timer
interval:1000
repeat:true
running:false
propertyintcount:0
onTriggered:{
count+=1
varidx=count%groups.model.rowCount()
console.log('timertrigger',idx,count)
groups.currentIndex=idx
}
}
Component{
id:ruleDelegate
RowLayout{
id:ruleName
width:300
height:40
Label{
verticalAlignment:Text.AlignVCenter
horizontalAlignment:Text.AlignHCenter
text:["<b>",model.name,"<b>"].join('')
Layout.fillWidth:true
Layout.preferredWidth:3
}
}
}
GridView{
id:rulesView
anchors.fill:parent
cellHeight:50
cellWidth:220
delegate:ruleDelegate
}
Component.onCompleted:{
timer.running=true
console.log('mainload',ruleGroupsModel)
}
}
####### end of Test.qml ############
Thanks !
--
songchunyi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20170403/488ddd6c/attachment-0001.html>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Test.qml
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20170403/488ddd6c/attachment-0001.ksh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testmodel.py
Type: application/octet-stream
Size: 2275 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20170403/488ddd6c/attachment-0001.obj>
More information about the PyQt
mailing list