Forums

OverviewV-Play 2 Support (Qt 5) › Repeater and property bindings

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #12122

    Phil

    Hi. I have a select level scene in my game. When the player completes a level, I want the select level scene to update the button for that level. I use a repeater for my buttons and I’m trying to update the button using a property binding but this doesn’t work. I could use the ‘repeater.itemAt()’ function but my levels are spread across several repeaters (repeater1, repeater2, etc) so the code gets a bit messy. I’ve pasted some sample code below:

    Main.qml

    import VPlay 2.0
    import QtQuick 2.0
    import "common"
    
    GameWindow {
        id: gameWindow
        width: 480
        height: 320
    
        property int levels: 4
        property int currentLevel: 0
        property var levelsComplete: [0,0,0,0]
    
        // bg
        Rectangle{
            anchors.fill: parent
            color: "#ece468"
        }
    
        // instructions
        Text {
            anchors.horizontalCenter: parent.horizontalCenter
            y: 50
            text: "Click on a button to complete the level!"
            font.pixelSize: 20
        }
    
        // levels
        Row {
            id: row
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: 10
            Repeater {
                id: repeater
                model: levels
                MenuButton {
                    text: modelData+1
                    width: 40
                    height: 40
                    isComplete: levelsComplete[modelData] === 1
                    onClicked: {
                        currentLevel = modelData
                        
                        // ...
                        // load a level 
                        // ...
    
                        // repeater.itemAt() works as expected
    //                    repeater.itemAt(currentLevel).isComplete = true
    
                        // property binding doesn't work
                        levelsComplete[currentLevel] = 1
                        console.debug(JSON.stringify(levelsComplete))
                    }
                }
            }
        }
    }
    

    MenuButton.qml

    import QtQuick 2.0
    
    Item {
        id: button
        // this will be the default size, it is same size as the contained text + some padding
        width: buttonText.width + paddingHorizontal*2
        height: buttonText.height + paddingVertical*2
    
        // the horizontal margin from the Text element to the Rectangle at both the left and the right side.
        property int paddingHorizontal: 10
        // the vertical margin from the Text element to the Rectangle at both the top and the bottom side.
        property int paddingVertical: 5
    
        // access the text of the Text component
        property alias text: buttonText.text
    
        // this handler is called when the button is clicked.
        signal clicked
    
        property bool isComplete: false
    
        Rectangle {
            id: normal
            anchors.centerIn: parent
            width: parent.width
            height: parent.height
            color: "#e9e9e9"
            radius: 10
        }
    
        Text {
            id: buttonText
            anchors.centerIn: parent
            font.pixelSize: 18
            color: "black"
        }
    
        Rectangle {
            id: green
            visible: isComplete
            anchors.fill: parent
            color: "#63fd78"
            radius: 10
        }
    
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            hoverEnabled: true
            onClicked: {
                if(!isComplete)
                    button.clicked()
            }
            onPressed: button.opacity = 0.5
            onReleased: button.opacity = 1
        }
    }
    

    Thanks,

    Phil

    #12132

    Günther
    V-Play Team

    Hi Phil!

    Property bindings also work when using a Repeater. The problem here is just that changes within an array (levelsComplete) are not recognized as a change in the property value, thus no bindings are updated. If you copied the array and set the levelsComplete property to the new value, you’ll see that the binding works:

    onClicked: {
      currentLevel = modelData
    
      var copy = []
      for(var i = 0; i < levelsComplete.length; i++)
        copy[i] = levelsComplete[i]
    
      copy[currentLevel] = 1
      levelsComplete = copy // signals property change
      console.debug(JSON.stringify(levelsComplete))
    }

    However, I think this is not a very good solution. A better solution would be to manually signal the property change:

    onClicked: {
      currentLevel = modelData
    
      levelsComplete[currentLevel] = 1 // changes within the array do not signal levelsCompleteChanged
      console.debug(JSON.stringify(levelsComplete))
      gameWindow.levelsCompleteChanged() // signal property change manually
    }

     

    Best,
    Günther

     

     

     

    • This reply was modified 2 years, 6 months ago by  GT.
    • This reply was modified 2 years, 6 months ago by  GT.
    #12135

    Phil

    Great, thanks! Using levelsCompleteChanged() is a neat solution :)

Viewing 3 posts - 1 through 3 (of 3 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support