gridviewqmlqtquick2listmodel

How to change the content in specified GridView element with index number


i am building a project's front-end side with QtQuick2. I am having a trouble with popup styled elements. I created a ListElement first, then created a GridView and put ListElement elements into that by using model. That is a 3x3 grid and what i am trying to do is when user clicked on an element, i want the change background image of that element.

default state

default state

expected state

expected state

It happens but it stays under the other elements of grid. I tried to set visibility of element which stays upper on z-index but i was not able to reach grid[index]'s properties. Here is what happens

my build

tested version of state

Here is my code

import QtQuick
import QtQuick.Layouts 1.12

Item {

Text {
    id: textDevice
    x: 312
    y: 69
    text: "CİHAZ AYARLARI"
    color: "#4A4A4A"
    font.pixelSize: 22
    font.weight: 400
    font.family: "SF Pro Text"
}


ListModel {
    id: deviceSettings
    ListElement { name: "DİL SEÇİMİ";  src:"/images/deviceSettingsRect.png"; status:"disabled" }
    ListElement { name: "WIFI AYARLARI";  src:"/images/deviceSettingsRect.png" }
    ListElement { name: "GÜÇ KORUMASI";  src:"/images/deviceSettingsRect.png" }
    ListElement { name: "TARİH AYARI"; src:"/images/deviceSettingsRect.png" }
    ListElement { name: "KAYIT PERİYODU"; src:"/images/deviceSettingsRect.png" }
    ListElement { name: "E-POSTA AYARLARI";  src:"/images/deviceSettingsRect.png"}
    ListElement { name: "SAAT AYARI";  src:"/images/deviceSettingsRect.png" }
    ListElement { name: "RAKIM"; src:"/images/deviceSettingsRect.png" }
    ListElement { name: "SMS AYARLARI";  src:"/images/deviceSettingsRect.png" }
}


GridView {
    id: deviceGrid
    anchors.fill: parent
    anchors.leftMargin: 104
    anchors.topMargin: 152
    model: deviceSettings
    cellHeight: 75
    cellWidth: 205
    delegate: Rectangle {
        id: deviceRects
        width: 182
        height: 68
        color: "transparent"
        z: 900

        Text{
            color: "#4A4A4A"
            text: name
            font.family: "SF Pro Text"
            font.weight: 400
            font.pixelSize: 14
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: parent.top
            anchors.topMargin: 25
            z: 999
        }

        Image {
            id: deviceBackground
            anchors.fill: parent
            source: src
        }

        MouseArea{
            anchors.fill: parent
            onClicked: {
                deviceGrid.currentIndex = index;

                if(name==="DİL SEÇİMİ"){
                    if(status==="enabled"){
                        deviceRects.width = 182
                        deviceRects.height = 143
                        deviceBackground.source = "/images/langSelect.png"
                        console.log(index)
                        status="disabled"
                    }else{
                        deviceRects.width = 182
                        deviceRects.height = 68
                        deviceBackground.source = "/images/deviceSettingsRect.png"
                        status="enabled"
                    }
                }else if(name==="WIFI AYARLARI"){
                    if(status==="enabled"){
                        deviceRects.width = 182
                        deviceRects.height = 143
                        deviceBackground.source = "/images/langSelect.png"
                        console.log(index)
                        status="disabled"
                    }else{
                        deviceRects.width = 182
                        deviceRects.height = 68
                        deviceBackground.source = "/images/deviceSettingsRect.png"
                        status="enabled"
                    }
                }

            }
        }


        }


    }


}

I reviewed this How to access the property of a GridView - or ListView - element but still wasn't able to figure it out. Any suggestions? If i can reach the index number of 2nd row 1st column, i would hide it by visibility property but i could not.

Extra quick question(later edit) I want to create a timer setter in one of these pop-ups. When user click they should see this inside 3rd row 1st column.

enter image description here

I've created a timer which takes the current time from computer. I want user to be able to change it by this pop-up. Here is my timer

Timer{
    interval : 500
    running : true
    repeat : true

    onTriggered: {
        var date = new Date()
        clockText.text = date.toLocaleTimeString(Qt.locale("en_US"), "hh:mm")
    }
}

I can use up/down arrows or something else instead of upper or lower number previews but how can i set it in ListElement and save as original value. I checked on

Time input field in QML

Time Picker in QML

How to add Date and Time picker in qt qml


Solution

  • I wouldn't increase the size of the elements inside the cells, but use a popup which opens on top. I've changed your code in order for it to work as expected without using the images, because they are not available to us. Have a look at how the z property of the Rectangle is used when its height gets increased. I set it to 1 when it is active and set it back to 0 if not.

    import QtQuick
    import QtQuick.Controls
    
    Window {
        id: root
        width: 1024
        height: 768
        visible: true
        color: "#aaddff"
    
        ListModel {
            id: deviceSettings
            ListElement { name: "DİL SEÇİMİ" }
            ListElement { name: "WIFI AYARLARI" }
            ListElement { name: "GÜÇ KORUMASI" }
            ListElement { name: "TARİH AYARI" }
            ListElement { name: "KAYIT PERİYODU" }
            ListElement { name: "E-POSTA AYARLARI" }
            ListElement { name: "SAAT AYARI" }
            ListElement { name: "RAKIM" }
            ListElement { name: "SMS AYARLARI" }
        }
    
        GridView {
            id: deviceGrid
            anchors.fill: parent
            anchors.leftMargin: 104
            anchors.topMargin: 152
            model: deviceSettings
            cellHeight: 75
            cellWidth: 205
            currentIndex: -1
    
            delegate: Rectangle {
                id: deviceRects
                width: 182
                height: 68
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "#f7f9f9" }
                    GradientStop { position: 1.0; color: "#c5dcec" }
                }
                radius: 20
                border.color: mouseArea.containsMouse ? "gray" : "#ffffff"
                border.width: 2
    
                Text {
                    color: "#4A4A4A"
                    text: name
                    font.family: "SF Pro Text"
                    font.weight: 400
                    font.pixelSize: 14
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.top: parent.top
                    anchors.topMargin: 25
                }
    
                states: [
                    State {
                        name: "default"
                        when: deviceGrid.currentIndex !== index
                        PropertyChanges {
                            target: deviceRects
                            height: 68
                            z: 0
                        }
                    },
                    State {
                        name: "active"
                        when: deviceGrid.currentIndex === index
                        PropertyChanges {
                            target: deviceRects
                            height: 143
                            z: 1
                        }
                    }
                ]
    
                MouseArea {
                    id: mouseArea
                    anchors.fill: parent
                    hoverEnabled: true
                    onClicked: {
                        if (deviceGrid.currentIndex === index)
                            deviceGrid.currentIndex = -1
                        else
                            deviceGrid.currentIndex = index
                    }
                }
            }
        }
    }