Model property(roles) unwanted update when switching between views and models
-
I am new to QML and QtQuick. My problem is I have two views in QML. The view contains Repeater with a subclass of
QAbstractListModel
named ``TestingModel``` model from python Code. In python I had to instantiated two models let say :mymodel = TestingModel() mymodeltwo = TestingModel()
then I expose both to QML using
QmlApplicationEngine().contextProperty()
method.
model :engine.rootContext().setContextProperty("mymodel" ,mymodel) engine.rootContext().setContextProperty("mymodeltwo", mymodeltwo)
Then I have
main.qml
which contain ColumnLayout with two Rectangle , on the first Rectangle contain five circle from Component created using Repeater with model I mentioned before, the code :import QtQuick 2.0 import QtQuick.Layouts 1.4 import QtQuick.Controls 2.0 ApplicationWindow { id: page width: 800 height: 480 visible: true ColumnLayout{ anchors.top : parent.top anchors.fill : parent Rectangle{ id : container1 color : "yellow" Layout.fillHeight: true Layout.fillWidth: true StackView{ id : circlestackview initialItem : fivecirclefirst } } Rectangle{ id : container2 color : "red" Layout.fillHeight: true Layout.fillWidth: true } Button{ id : resetbutton flat : true highlighted : true text : "ChangeColor" Layout.fillWidth: true onClicked:{ updater.run() } } Switch{ id : changeloader checked : false text : "one" onClicked:{ changeloader.text = checked ? "two" : "one" if (checked == true){ circlestackview.push(fivecirclesecond) console.log("pushed") } else{ circlestackview.pop() console.log("poped") } } } }
Switch will push component with id
fivecirclesecond
and pop that components in stackview. I also have button to change item value which represent color in the first model only not the second model when clicked.In the same file , I have two components that loaded in stackview :
Component{ id : fivecirclefirst ColumnLayout{ Flow{ id : flow1 spacing: 6 Repeater{ id : repeater1 model : mymodel delegate : Component{ Rectangle{ // required property color colorchannel height: 50 width: 50 border.color: "green" border.width: 1 radius: 30 color : model.colorchannel } } } } Flow{ spacing: 6 Repeater{ id : repeater2 model : mymodeltwo delegate : Component{ Rectangle{ // required property color colorchannel height: 50 width: 50 border.color: "green" border.width: 1 radius: 30 color : model.colorchannel } } } } } } Component{ id : fivecirclesecond ColumnLayout{ Flow{ spacing: 6 Repeater{ id : repeater3 model : mymodel delegate : Component{ Button{ // required property color colorchannel height: 50 width: 50 background:Rectangle{ border.color: "green" border.width: 1 // radius: 30 color : model.colorchannel } } } } } Flow{ spacing: 6 Repeater{ id : repeater4 model : mymodeltwo delegate : Component{ Button{ // required property color colorchannel height: 50 width: 50 // radius: 30 background:Rectangle{ color : model.colorchannel border.color: "green" border.width: 1 } } } } } } } }
Then my python class model :
alfabet = [ ["A", 1], ["B", 1], ["C", 1], ["D", 1], ["E", 1], ] class TestingModel(QAbstractListModel): def __init__(self, parent =None ) -> None: super().__init__(parent) self.channel = alfabet self.initialize_role() def initialize_role(self): self.statechannel = Qt.UserRole + 1 def rowCount(self, parent: QModelIndex = None) -> int: return len(self.channel) def columnCount(self, parent: QModelIndex = None) -> int: return len(self.channel[0]) def data(self, index, role): row = index.row() if not index.isValid: return QVariant() if role == Qt.DisplayRole : return self.channel[row] if role == self.statechannel: if self.channel[row][1] == 1 : return "green" elif self.channel[row][1] == 0 : return "blue" else : return "darkgray" def roleNames(self): dict= {} dict = { self.statechannel : QByteArray(b"colorchannel") } return dict def updateData(self, channel, val): index_status = self.createIndex(channel, 1) res = self.setData(index_status, val, self.statechannel) def setData(self, index: QModelIndex, value, role = Qt.EditRole) -> bool: if not index.isValid() : return QVariant() if role == Qt.EditRole: return True elif role == self.statechannel: row = index.row() column = index.column() self.channel[row][column] = value self.dataChanged.emit(index,index, [self.statechannel]) return True
The application run like this :
when I switch with Switch Button then It change to Buttons:
Then I clicked Change Color to change first model items only :
I Switch to the first view ,it's okay no problem :
But the problem is when after this state, I switch back again to previous view :
Meanwhile the bottom five button has different model with top. and how can datachanged item roles mixed between two distict model?? -