QtQuick : Helmo's rewrite - part 3

parse error

Today we're going to play a bit with a ListView. A ListView is a simple but powerful widget that shows items in a list. In Helmo, the main menu I'm working on is a customized ListView.

Let's see how to start. We are going to start a new QML file. Let's call it MyList.qml :

import QtQuick 1.0

ListView {
    id: myList

    anchors.bottom: parent.bottom
    height: parent.height*0.25
    width: parent.width
    boundsBehavior: Flickable.DragOverBounds
    cacheBuffer: width
    focus: true
    highlightMoveDuration: 300
    orientation: ListView.Horizontal
    snapMode: ListView.SnapToItem
    spacing: 20
}

As you can see, we've built a simple horizontal list view (orientation property). The view will stick to its parent bottom (anchors.bottom property). We've also set a height and width. I strongly recommend you to RTFM if you want to know more about others properties :P

We still miss two important things : the data and how the data is displayed. Well, the list view is able to get the data from a model (you know MVC, right ?), thanks to the model property. Here, we're going to use a simple ListModel, but keep in mind that you can build your own model if you need to. Let's have a look at this model, stored in the MyListModel.qml file :

import QtQuick 1.0

ListModel {
    ListElement {
         name: "Plugin 1"
    }
    ListElement {
         name: "Plugin 2"
    }
    ListElement {
         name: "Plugin 3"
    }
    ListElement {
         name: "Plugin 4"
    }
    ListElement {
         name: "Plugin 5"
    }
    ListElement {
         name: "Plugin 6"
    }
}

Pretty easy to understand, isn't it ?

Now that the list view knows what to display, we still have to tell it how to display the data. Once again, the list view is very smart. It provides a delegate property to do that. A delegate is a simple template defining each item instanciated by the list view. And guess what, a delegate is a Component. So we're almost free to do whatever we want.

For this example, I chose a simple 256x75 text button as delegate. The source code is as follow :

Rectangle {
    color: "transparent"
    height: 75
    width: 256
    Text {
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        color: "#FFFFFF"
        font.pointSize: 32
        horizontalAlignment: Text.AlignHCenter
        text: name
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log(name)
        }
    }
}

Now that everything is ready, let's stick all the pieces together. MyList.qml source code becomes :

import QtQuick 1.0

ListView {
    id: myList

    anchors.bottom: parent.bottom
    height: parent.height*0.25
    width: parent.width
    boundsBehavior: Flickable.DragOverBounds
    cacheBuffer: width
    focus: true
    highlightMoveDuration: 300
    orientation: ListView.Horizontal
    snapMode: ListView.SnapToItem
    spacing: 20

    model: MyListModel {}

    delegate : Component {
        Rectangle {
            color: "transparent"
            height: 75
            width: 256
            Text {
                anchors.bottom: parent.bottom
                anchors.horizontalCenter: parent.horizontalCenter
                color: "#FFFFFF"
                font.pointSize: 32
                horizontalAlignment: Text.AlignHCenter
                text: name
            }

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log(name)
                }
            }
        }
    }
}

Notice that I could have put the delegate in a seperate file (and I strongly encourage you to do so).

And do not forget to update your HelloWorld.qml file to add the list view :

import QtQuick 1.0

Rectangle {
    id: appWindow

    color: "#111"
    width: 1360
    height: 768
    Text {
        anchors.centerIn: parent
        font.pointSize: 32
        color: "white"
        text: hello.foo
    }

    MyList {}
}

Now just launch the Python file and see the magic happen. Isn't it great to build such a thing in minutes ?