Today I did some more work on my Windows Phone hub project in QML and updated the wiki for it. You can see it at Can QtQuick create a Windows Phone Hub?
Whilst doing this I discovered more joys and frustrations of QML, QmlViewer and ListViews.
How to respond to clicks and update the selection in a ListView:
This was frustrating to work with. List Views so far had been great – the system with delegates seemed intuitive, they had in built mouse/finger control as they inherited Flickable and the did a good job of laying things out and scrolling and enabling that bounce animation when you reached the end of the list. So here’s the news:
- Which flicking is built in, clicking is not, you still need a mouseArea for this
- You can’t do someting like listView.currentItem=anything, you have to get it’s index, and the ListView provides no indexOf(Item) method to do that.
So here is a code snippet from my Windows Phone hub qml file that does both things. Not that the mouseArea is on the delegate.
VisualDataModel {
id: galleryItemModel
model :ListModel {
id: albumModel
}
delegate:
Rectangle{
width: itemText.width+10; height: itemText.height+5
color: "#00000000"
id:menuItem
Text{id:itemText
font{family:fontName; bold: true} color: textColor
text: album
}
MouseArea{
anchors.fill: parent
onClicked: albumList.currentIndex = index }
}
}
ListView {
id: albumList
anchors.fill: parent;
model: galleryItemModel
orientation: ListView.Vertical
flickDeceleration: 2000
cacheBuffer: 200
highlightFollowsCurrentItem: true
highlight: Rectangle { width: currentItem.width; color: "#00000000"; border {color:"#ffffff"; width:2} radius: 5}
currentIndex: 0
onCurrentIndexChanged: {
highlightItem.width=currentItem.width;
ImageLoader.createRecents(currentIndex);
ImageLoader.createImages(currentIndex);
}
So, did you notice in the mouse area what you have to do to set the current item – yes, set the currentIndex=index. This is much nicer than what I originally thought, the only frustration being that I wasn’t able to find documentation on this earlier (or more easily) – thanks to brasser for pointing this out.
GridView has no cell spacing
This i find hard to believe but seems to be true. For spacing, in the grid view, set your cellWidth and cellHeight to be whatever you want, and the set the size of the ListElement or delegate to be smaller than it.
QMLViewer and recording videos
It has a menu item to record a video, which I tried to do today to demo my hub. Inside the simulator the option for where to save it came up and I chose a location. In the output windows of Qt it said “Recording ON” or something like that and showed my application again. After doing the actions to demo it I when back to the menu and chose Stop recording. The output windows showed “Recording OFF. writing file (path)” or something like that. I went to the path location. Nothing there.
QT Creator – Refresh Project
So in Qt Creator we have quite a good software development environment. You can manage your projects including adding and removing files. What you can’t do is this – If you know your project folders changed outside of QT (say you had an Images folder and you dropped some more images into it using Windows Explorer) these files won’t show up automatically. There must be a refresh somewhere but I can’t find it. The solution: close your project and open it again.
Overall I like QML and Qt Creator and QMLViewer and all the emulators – it’s a great package. Some of these things were annoying though and I hope you may save yourself the frustration I had trying to figure these things out.
Interesting post, I was struggling to find out how to make lists actually clickable as well. Do you have any idea what you would need to do if you wanted a clickable list while define the delegate in a separate file? Anything simpler than creating custom signals and slots?
It does seem odd that lists arn’t clickable by default…
For information, a better code for the MouseArea of the delegate would be:
MouseArea {
anchors.fill: parent
onClicked: ListView.view.currentIndex = index
}
That way the delegate doesn’t need to know the name of the ListView and there can be more than one ListView.