Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Model property(roles) unwanted update when switching between views and models
Qt 6.11 is out! See what's new in the release blog

Model property(roles) unwanted update when switching between views and models

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 294 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.
  • S Offline
    S Offline
    satriyosan
    wrote on last edited by
    #1

    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 :
    first_appearance.png
    when I switch with Switch Button then It change to Buttons:
    second_appearance.png
    Then I clicked Change Color to change first model items only :
    after_clicked.png
    I Switch to the first view ,it's okay no problem :
    afterback.png
    But the problem is when after this state, I switch back again to previous view :
    b9cfe9a7-c263-4b38-8bed-315f79d51029-image.png
    Meanwhile the bottom five button has different model with top. and how can datachanged item roles mixed between two distict model??

    1 Reply Last reply
    0
    • S satriyosan referenced this topic on

    • Login

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