среда, 28 марта 2012 г.

QML. Первое приложение для Nokia N9.

Как и обещал ранее в целях изучения я написал маленькое приложение на QML.
Я прочитал на хабре статью Как легко творить прекрасное и взял код из этой статьи за основу.
Была задача на сделать законченное приложение показывающее картинки из интернета и имеющее элементы управления.
"Прекрасное" с хабрахабра дало мне дополнительные силы и заставляло концентрироваться на документации.

Вот что из этого получилось.


Вся программа составляет примерно 290 срок.
Можно скопировать ее отсюда и вставить в новый проект Qt Creator, заменив содержимое main.qml

import QtQuick 1.1
import com.nokia.meego 1.0

Window {
    id: mainWnd
    width: 480
    height: 854

    property real interVal: 5000
    property int y1: 0
    property int y2: 0

    function getPictureURL(){
        var str = '' + Math.round(Math.random() * 5055);
        while (str.length < 5) {
            str = '0' + str;
        }
        var url = "http://media.oboobs.ru/boobs/"+ str + ".jpg";
        return url;
    }

    state: (screen.currentOrientation === Screen.Portrait) ? "portrait" : "landscape"

    states: [
        State {
            name: "landscape"
            PropertyChanges { target: aRectStatMsg; width: 814}

            PropertyChanges { target: aRectChangeDealy; x: 20}
            PropertyChanges { target: aRectChangeDealy; y: 80}
            PropertyChanges { target: aRectChangeDealy; width: 550}
            PropertyChanges { target: aRectChangeDealy; height: 380}

            PropertyChanges { target: aRectReloadPic; x: 590}
            PropertyChanges { target: aRectReloadPic; y: 80}
            PropertyChanges { target: aRectReloadPic; width: 244}
            PropertyChanges { target: aRectReloadPic; height: 180}

            PropertyChanges { target: aRectPausePic; x: 590}
            PropertyChanges { target: aRectPausePic; y: 280}
            PropertyChanges { target: aRectPausePic; width: 244}
            PropertyChanges { target: aRectPausePic; height: 180}

            PropertyChanges { target: arrow_uppng; anchors.topMargin: 33}
            PropertyChanges { target: arrow_downpng; anchors.bottomMargin: 33}
        },
        State {
            name: "portrait"
            PropertyChanges { target: aRectStatMsg; width: 440}

            PropertyChanges { target: aRectChangeDealy; x: 20}
            PropertyChanges { target: aRectChangeDealy; y: 80}
            PropertyChanges { target: aRectChangeDealy; width: 260}
            PropertyChanges { target: aRectChangeDealy; height: 740}

            PropertyChanges { target: aRectReloadPic; x: 300}
            PropertyChanges { target: aRectReloadPic; y: 80}
            PropertyChanges { target: aRectReloadPic; width: 160}
            PropertyChanges { target: aRectReloadPic; height: 362}

            PropertyChanges { target: aRectPausePic; x: 300}
            PropertyChanges { target: aRectPausePic; y: 457}
            PropertyChanges { target: aRectPausePic; width: 160}
            PropertyChanges { target: aRectPausePic; height: 363}

            PropertyChanges { target: arrow_uppng; anchors.topMargin: 80}
            PropertyChanges { target: arrow_downpng; anchors.bottomMargin: 80}
        }
    ]


    Image {
        id: image1
        opacity: 1
        fillMode: Image.PreserveAspectFit
        anchors.fill: parent
        source: ""
        onStatusChanged: if (status === Image.Error) source = getPictureURL()
    }

    Timer {
        id: myTimer
        interval: mainWnd.interVal
        running: true
        repeat: true
        onTriggered: image1.source = getPictureURL()
    }

    Rectangle {
        id: layerControl
        anchors.fill: parent
        color: "transparent"
        opacity: 0.4
        radius: 10
        property bool activOpacity: false

        states:[
            State {
                name: "showOn"; when: layerControl.activOpacity === true
                PropertyChanges { target: layerControl; opacity: 0.7; }
            },
            State {
                name: "showOff"; when: layerControl.activOpacity === false
                PropertyChanges { target: layerControl; opacity: 0.01 }
            }
        ]

        transitions: [
            Transition {
                from: "showOff"; to: "showOn";
                NumberAnimation { properties: "opacity"; duration: 100 }
            },

            Transition {
                from: "showOn"; to: "showOff";
                NumberAnimation { properties: "opacity"; duration: 1000 }
            }
        ]

        Rectangle {
            id: aRectStatMsg
            x: 20
            y: 20
            width: 440
            height: 40
            radius: parent.radius
            color: "steelblue"

            Text {
                id: actionDescription
                x: 10
                font.family: "Helvetica"
                font.bold: true
                font.pixelSize: 32
                color: "#35bcff"
                text: ""
             }
        }

        Rectangle {
            id: aRectChangeDealy
            x: 20
            y: 80
            width: 260
            height: 740
            radius: parent.radius
            color: "steelblue"

            MouseArea {
                anchors.fill: parent

                onPositionChanged: {
                    mainWnd.y1 = mainWnd.y2
                    mainWnd.y2 = mouseY
                    if ((mainWnd.y2 - mainWnd.y1) > 0)
                        mainWnd.interVal += 100
                    else
                        mainWnd.interVal -= 100
                    if ( mainWnd.interVal < 1000)
                        mainWnd.interVal = 1000
                    actionDescription.text = "SlideShow Timeout = " + Math.round(mainWnd.interVal / 1000)  + "sec"
                    console.log("PositionChanged: " + mainWnd.y1 + ", " + mainWnd.y2)
                }
                onPressed: {
                    layerControl.activOpacity = true
                    console.log("aRectChangeDealy pressed")
                }
                onReleased: {
                    layerControl.activOpacity = false
                    console.log("aRectChangeDealy released")
                }
            }

            Image {
                id: arrow_uppng
                anchors.horizontalCenter: aRectChangeDealy.horizontalCenter
                anchors.top: aRectChangeDealy.top
                anchors.topMargin: 80
//                y: 80
                source: "arrow_up.png"
                MouseArea {
                    anchors.fill: parent

                    onPressed: {
                        mainWnd.interVal -= 1000
                        if ( mainWnd.interVal < 1000)
                            mainWnd.interVal = 1000
                        actionDescription.text = "SlideShow Timeout = " + Math.round(mainWnd.interVal / 1000)  + "sec"
                        layerControl.activOpacity = true
                        console.log("arrow_uppng pressed")
                    }
                    onReleased: {
                        layerControl.activOpacity = false
                        console.log("arrow_uppng released")
                    }
                }
            }

            Image {
                id: arrow_downpng
                anchors.horizontalCenter: aRectChangeDealy.horizontalCenter
                anchors.bottom: aRectChangeDealy.bottom
                anchors.bottomMargin: 80
//                y: 532
                source: "arrow_down.png"
                MouseArea {
                    anchors.fill: parent

                    onPressed: {
                        mainWnd.interVal += 1000
                        actionDescription.text = "SlideShow Timeout = " + Math.round(mainWnd.interVal / 1000)  + "sec"
                        layerControl.activOpacity = true
                        console.log("arrow_downpng pressed")
                    }
                    onReleased: {
                        layerControl.activOpacity = false
                        console.log("arrow_downpng released")
                    }
                }
            }

        }

        Rectangle {
            id: aRectReloadPic
            x: 300
            y: 80
            width: 160
            height: 362
            radius: parent.radius
            color: "steelblue"
            Image {
                anchors.horizontalCenter: aRectReloadPic.horizontalCenter
                anchors.verticalCenter: aRectReloadPic.verticalCenter
                id: repeatpng
                source: "repeat.png"
            }

            MouseArea {
                anchors.fill: parent

                onPressed: {
                    image1.source = getPictureURL()
                    myTimer.restart()
                    actionDescription.text = "Loading next picture"
                    layerControl.activOpacity = true
                    console.log("aRectReloadPic pressed")
                    if (image1.status == Image.Error) console.log('Ошибка загрузки картинки')
                }
                onReleased: {
                    layerControl.activOpacity = false
                    console.log("aRectReloadPic released")
                }
            }
        }

        Rectangle {
            id: aRectPausePic
            x: 300
            y: 457
            width: 160
            height: 363
            radius: parent.radius
            color: "steelblue"
            Image {
                anchors.horizontalCenter: aRectPausePic.horizontalCenter
                anchors.verticalCenter: aRectPausePic.verticalCenter
                id: pausepng
                source: "pause.png"
            }
            MouseArea {
                anchors.fill: parent

                onPressed: {
                    myTimer.stop()
                    actionDescription.text = "SlideShow stoped"
                    layerControl.activOpacity = true
                    console.log("aRectPausePic pressed")
                }
                onReleased: {
                    layerControl.activOpacity = false
                    console.log("aRectPausePic released")
                }
            }
        }
    }
}
Скомпилированное приложение можно скачать по этой ссылке: slideshow_0.1.1_armel.deb
Полностью проект (tarball) можно скачать по это1 ссылке: bobshow_v0.1.1.tar.gz