Horizontal Flow example shows how to implement a horizontally flickable list of items like a list of album covers. The component is based on the PathView element. Also, horizontal alphabetic scrollbar is provided on the bottom of the page for quickly jumping to a new position. Horizontal Flow also supports arrow key-based navigation for media center-style UIs.
Show code ยป
horizontalflow.qml:
import QtQuick 1.0 Rectangle { color: "black" width: 800; height: 280 HorizontalPathView { id: horizontalPathView model: Model { id: model } delegate: Delegate {} anchors.fill: parent } AlphabeticScrollbar { view: horizontalPathView alphabets: model.alphabets alphabetIndeces: model.alphabetIndeces anchors { left: parent.left right: parent.right bottom: parent.bottom margins: 3 } } }
HorizontalPathView.qml:
import QtQuick 1.0 PathView { id: horizontalPathView focus: true highlight: Item {} pathItemCount: 11 preferredHighlightBegin: 0.5; preferredHighlightEnd: 0.5 path: Path { startX: -400; startY: horizontalPathView.height/2-70 PathAttribute { name: "iconScale"; value: 0.5 } PathQuad { x: horizontalPathView.width/2 y: horizontalPathView.height/2-20 controlX: horizontalPathView.width/4 controlY: horizontalPathView.height/2-45 } PathAttribute { name: "iconScale"; value: 1.0 } PathQuad { x: horizontalPathView.width+400 y: horizontalPathView.height/2-70 controlX: 3*horizontalPathView.width/4 controlY: horizontalPathView.height/2-45 } PathAttribute { name: "iconScale"; value: 0.5 } } Keys.onLeftPressed: decrementCurrentIndex() Keys.onRightPressed: incrementCurrentIndex() function zLevel(index) { var dist = Math.abs((currentIndex - index) % count) if (dist > (pathItemCount/2.0 + 1)) dist = count - dist return Math.floor(pathItemCount/2.0) - dist } }
Model.qml:
import QtQuick 1.0 ListModel { property variant alphabets: [] property variant alphabetIndeces: [] function calculateAlphabets() { var newAlphabets = [] var newAlphabetIndeces = [] var previousItem, item = " " for (var index = 0; index < count; index++) { previousItem = item item = get(index).item if (previousItem.charAt(0) != item.charAt(0)) { newAlphabets[newAlphabets.length] = item.charAt(0) newAlphabetIndeces[newAlphabetIndeces.length] = index } } alphabets = newAlphabets alphabetIndeces = newAlphabetIndeces } Component.onCompleted: populate() function populate() { // go from A to Z for (var index = 65; index < 91; index++) { var alphabet = String.fromCharCode(index) var alphabetCount = Math.floor(Math.random()*5) for (var index2 = 0; index2 < alphabetCount; index2++) append({"number": count, "item": alphabet}) } calculateAlphabets() } }
Delegate.qml:
import QtQuick 1.0 Rectangle { width: 200; height: 200 scale: PathView.iconScale z: PathView.view.zLevel(index) color: Qt.rgba(0.5+(PathView.view.count - number)*Math.random()/PathView.view.count, 0.3+number*Math.random()/PathView.view.count, 0.3*Math.random(), 0.7) signal clicked Keys.onReturnPressed: clicked() onClicked: PathView.view.currentIndex = index MouseArea { id: delegateMouse anchors.fill: parent onClicked: parent.clicked() } Rectangle { color: Qt.rgba(0.2, 0.3, 0.8) opacity: delegateMouse.pressed ? 0.8 : 0.0 anchors.fill: parent } Text { smooth: true color: "white" font.pixelSize: 30 text: "ITEM\n" + item anchors.centerIn: parent horizontalAlignment: Text.AlignHCenter } }
AlphabeticScrollbar.qml:
import QtQuick 1.0 MouseArea { width: 400; height: 50 property variant view property variant alphabets property variant alphabetIndeces property int currentIndex property real letterWidth: (width + 10)/alphabets.length onPressed: updatePosition(mouse.x) onPositionChanged: updatePosition(mouse.x) function updatePosition(x) { var index = Math.round((x-10)/letterWidth); if (index >= 0 && index < alphabetIndeces.length) { currentIndex = index; view.currentIndex = alphabetIndeces[index]; } } Rectangle { radius: 10 color: "white" visible: parent.pressed height: letterWidth+60; width: letterWidth+30 x: Math.min(Math.max(0,parent.mouseX-width/2), parent.width-width) anchors { bottom: parent.bottom; bottomMargin: -10 } Text { font.pixelSize: 34 text: alphabets[currentIndex] anchors { centerIn: parent; verticalCenterOffset: -20 } } } Rectangle { height: 20 color: Qt.rgba(1.0, 1.0, 1.0, 0.2) anchors {left: parent.left; right: parent.right; bottom: parent.bottom } } }
really cool and informative to understand QML and Path View!!!
I’m trying to write a Dock in QML that will be very close to the MacOSX dock:
Here’s what I’ve done so far:
http://tinypic.com/r/2mmipoj/5
I’ve been using a QML ListView for this, but after looking at your Horizontal Flow, maybe I should be using a QML PathView ????
Any thoughts?
Nice dock! ๐ Conceptually I think PathView would be more appropriate, but for sure you can create a dock with either ListView or PathView. PathView allows more freedom in specifying the path/route of the items being animated and allows carousel-style looping, but it is missing some flexibility, properties (positioning functions, section and spacing support, etc.) and some cases maturity of the more commonly used ListView.