Brent81
Brent81

Reputation: 1172

QT quick2 qml dynamic change GridView columns

I used a GridView to display a ListModel. Originally I set cellWidth to:

cellWidth = grid.width/3

to create a 3 columns grid. then I want to change the column count to 2, so I set cellWidth to:

cellWidth = grid.width/2

the GridView's display changed. But when I resize the container's desktop window, the cells in the gridview won't change size anymore.

what should I do to make it correct?

Please have a look at the following code:

import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0

ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480

menuBar: MenuBar {
    Menu {
        title: qsTr("File")
        MenuItem {
            text: qsTr("2 columns")
            onTriggered: grid.cellWidth = grid.width/2;
        }
        MenuItem {
            text: qsTr("3 columns")
            onTriggered: grid.cellWidth = grid.width/3;
        }
    }
}

GridView {
    id: grid
    anchors.fill: parent
    cellWidth: width / 3;
    cellHeight: 300;
    model: ListModel {
        ListElement {
            name: "Apple"
            cost: 2.45
        }
        ListElement {
            name: "Orange"
            cost: 3.25
        }
        ListElement {
            name: "Banana"
            cost: 1.95
        }
    }
    delegate : Rectangle {
        //anchors.fill: parent
        width: grid.cellWidth
        height: grid.cellHeight
        border.color: "green"
        border.width: 2
        color: "red"
    }
}
}

Upvotes: 6

Views: 6933

Answers (2)

Keithel
Keithel

Reputation: 275

The issue you were having is that bindings are not automatically set up when you're writing JavaScript (which you're doing in your onTriggered signal handlers).

It is possible to do bindings in Javascript (as opposed to pure QML property binding) using Qt.binding():

onTriggered: {
    columns = 2;
    grid.cellWidth = Qt.binding(function() { return grid.width/columns; });
}

While your onWidthChanged handler solution works, this is a cleaner solution.

See: http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascript for details on how this works.

Upvotes: 0

Brent81
Brent81

Reputation: 1172

I've solved the problem by defining onWidthChanged of the gridview.

import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    id: appwnd
    property int columns : 3;

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("2 columns")
                onTriggered: {
                    columns = 2;
                    grid.cellWidth = grid.width/columns;
                }
            }
            MenuItem {
                text: qsTr("3 columns")
                onTriggered: {
                    columns = 3;
                    grid.cellWidth = grid.width/columns;
                }
            }
        }
    }

    GridView {
        id: grid
        anchors.fill: parent
        cellWidth: width / 3;
        cellHeight: 300;
        model: ListModel {
            ListElement {
                name: "Apple"
                cost: 2.45
            }
            ListElement {
                name: "Orange"
                cost: 3.25
            }
            ListElement {
                name: "Banana"
                cost: 1.95
            }
        }
        delegate : Rectangle {
            //anchors.fill: parent
            width: grid.cellWidth
            height: grid.cellHeight
            border.color: "green"
            border.width: 2
            color: "red"
        }
        onWidthChanged: {
            grid.cellWidth = grid.width/appwnd.columns;
        }
    }
}

Upvotes: 9

Related Questions