I've been playing around with Qt and QML for almost eight months and the new declarative language from the Troll Tech Engineers has impressed many people out there. If you don't know what QML is then don't hesitate to take a look at Nokia's website, you will find many things about Qt and QML.
QML is a wonderful language especially for developing mobile applications, where people always want to have fun with the UI. Thats why the legend Symbian seemed to lost its glory, but soon after Nokia's announcement of Symbian port of Qt, there is been a huge increase of interest from the people to develop for mobile.
QML, the declarative language has the strong Qt C++ on its backend and is a very simple environment for Web Programmers and New Programmers who don't have much experience with traditional programming languages like C++, C# and Java.
So here is my Stopwatch code snippet programs source code.
MainUI: StopWatch.qml (Best viewed in Landscape View)
MainUI: StopWatch.qml (Best viewed in Portrait View)
Used QML component for NewLap: NewLap.qml (Best viewed in Landscape view)
Used QML component for NewLap: NewLap.qml (Best viewed in Landscape view)
The Javascript code that has been used to create the application logic is just embedded into the QML code. It is a much simple program and I have done it right after my Hello World! program in QML. And thats the beauty of QML.
Additional Note:
QML is a wonderful language especially for developing mobile applications, where people always want to have fun with the UI. Thats why the legend Symbian seemed to lost its glory, but soon after Nokia's announcement of Symbian port of Qt, there is been a huge increase of interest from the people to develop for mobile.
QML, the declarative language has the strong Qt C++ on its backend and is a very simple environment for Web Programmers and New Programmers who don't have much experience with traditional programming languages like C++, C# and Java.
So here is my Stopwatch code snippet programs source code.
MainUI: StopWatch.qml (Best viewed in Landscape View)
import Qt 4.7 Rectangle { id:parentContainer width:320 height: 240 focus:true Image { id: background width:parentContainer.width height:parentContainer.height source: "background.jpg" } FontLoader{ id:digitalFont source:"trana.ttf" } Keys.onSelectPressed:{ startButton.startFunction() } Keys.onSpacePressed:{ startButton.startFunction() } Keys.onEnterPressed:{ startButton.startFunction() } Keys.onLeftPressed:{ resumeButton.resumeFun() } Keys.onRightPressed:{ stopButton.stopFunction() } http://www.techieshome.in/2011/08/simple-application-in-qml-stop-watch.html Keys.onUpPressed:{ newLapButton.createNewLapRecord() } Keys.onDownPressed:{ resetButton.resetFun() } Keys.onAsteriskPressed:{ Qt.quit() } Keys.onContext2Pressed:{ Qt.quit() } Grid{ id:lapRecordView rows:4 columns:3 spacing:3 anchors.top:parent.top anchors.horizontalCenter:parent.horizontalCenter NewLapL{ id:lap1 text:"" states: [ State { name: "created" PropertyChanges { target: lap1 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap1; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap2 text:"" states: [ State { name: "created" PropertyChanges { target: lap2 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap2; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap3 text:"" states: [ State { name: "created" PropertyChanges { target: lap3 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap3; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap4 text:"" states: [ State { name: "created" PropertyChanges { target: lap4 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap4; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap5 text:"" states: [ State { name: "created" PropertyChanges { target: lap5 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap5; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap6 text:"" states: [ State { name: "created" PropertyChanges { target: lap6 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap6; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap7 text:"" states: [ State { name: "created" PropertyChanges { target: lap7 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap7; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap8 text:"" states: [ State { name: "created" PropertyChanges { target: lap8 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap8; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap9 text:"" states: [ State { name: "created" PropertyChanges { target: lap9 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap9; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap10 text:"" states: [ State { name: "created" PropertyChanges { target: lap10 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap10; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap11 text:"" states: [ State { name: "created" PropertyChanges { target: lap11 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap11; property: "width"; from: 0; duration: 200 } } ] } NewLapL{ id:lap12 text:"" states: [ State { name: "created" PropertyChanges { target: lap12 opacity:1.0 height: (parentContainer.height*7)/100 width: (parentContainer.width*29)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap12; property: "width"; from: 0; duration: 200 } } ] } } Row{ id:buttonRow spacing:5 anchors.bottom:parent.bottom anchors.bottomMargin:5 anchors.horizontalCenter:parent.horizontalCenter Rectangle{ id:startButton width:start.width + 9 height:start.height + 10 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: startIcon source: "qrc:/ok.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - start.width/2 height:parent.height-3 } SequentialAnimation{ id: startButtonAnimation running:false NumberAnimation { target: startButton; property: "y"; to: startButton.y - 15; duration: 300 } NumberAnimation { target: startButton; property: "y"; to: startButton.y; duration: 200 } NumberAnimation { target: startButton; property: "y"; to: startButton.y - 8; duration: 200 } NumberAnimation { target: startButton; property: "y"; to: startButton.y; duration: 200 } } Text { id: start text: "Start" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised color:"indigo" styleColor:"slateblue" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked: { startButton.startFunction() } } function startFunction() { clock.running = false; timer.milliSeconds = 0; timer.seconds = 0; timer.minutes = 0; timer.hours = 0; milli.text = "00" second.text = "00" minute.text = "00" hour.text = "00" lap1.text = "" lap2.text = "" lap3.text = "" lap4.text = "" lap5.text = "" lap6.text = "" lap7.text = "" lap8.text = "" lap9.text = "" lap10.text = "" lap11.text = "" lap12.text = "" lap1.opacity = 0 lap2.opacity = 0 lap3.opacity = 0 lap4.opacity = 0 lap5.opacity = 0 lap6.opacity = 0 lap7.opacity = 0 lap8.opacity = 0 lap9.opacity = 0 lap10.opacity = 0 lap11.opacity = 0 lap12.opacity = 0 lap1.state = "" lap2.state = "" lap3.state = "" lap4.state = "" lap5.state = "" lap6.state = "" lap7.state = "" lap8.state = "" lap9.state = "" lap10.state = "" lap11.state = "" lap12.state = "" newLapButton.lapCount = 0; clock.running = true; startButtonAnimation.running = true } } Rectangle{ id:stopButton width:stop.width + 9 height:stop.height + 10 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: stopIcon source: "qrc:/right.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - stop.width/2 height:parent.height-3 } SequentialAnimation{ id: stopButtonAnimation running:false NumberAnimation { target: stopButton; property: "y"; to: stopButton.y - 15; duration: 300 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y; duration: 200 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y - 8; duration: 200 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y; duration: 200 } } Text { id: stop text: "Stop" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked : { stopButton.stopFunction() } } function stopFunction() { clock.running = false stopButtonAnimation.running = true } } Rectangle{ id:resumeButton width:resume.width + 9 height:resume.height + 10 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: resumeIcon source: "qrc:/left.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - resume.width/2 height:parent.height-3 } SequentialAnimation{ id: resumeButtonAnimation running:false NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y - 15; duration: 300 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y; duration: 200 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y - 8; duration: 200 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y; duration: 200 } } Text { id: resume text: "Resume" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked: { resumeButton.resumeFun() } } function resumeFun() { resumeButtonAnimation.running = true if(timer.milliSeconds > 0 || timer.seconds > 0 || timer.minutes > 0 || timer.hours > 0) clock.running = true; else return; } } Rectangle{ id:newLapButton property int lapCount: 0 width:newLap.width + 9 height:newLap.height + 10 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: newLapIcon source: "qrc:/up.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - newLap.width/2 height:parent.height-3 } SequentialAnimation{ id: newLapButtonAnimation running:false NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y - 15; duration: 300 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y; duration: 200 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y - 8; duration: 200 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y; duration: 200 } } Text { id: newLap text: "New Lap" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked:{ newLapButton.createNewLapRecord() } } function createNewLapRecord() { newLapButtonAnimation.running = true if(newLapButton.lapCount == 0){ lap1.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap1.state = "created"; } if(newLapButton.lapCount == 1){ lap2.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap2.state = "created"; } if(newLapButton.lapCount == 2){ lap3.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap3.state = "created"; } if(newLapButton.lapCount == 3){ lap4.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap4.state = "created"; } if(newLapButton.lapCount == 4){ lap5.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap5.state = "created"; } if(newLapButton.lapCount == 5){ lap6.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap6.state = "created"; } if(newLapButton.lapCount == 6){ lap7.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap7.state = "created"; } if(newLapButton.lapCount == 7){ lap8.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap8.state = "created"; } if(newLapButton.lapCount == 8){ lap9.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap9.state = "created"; } if(newLapButton.lapCount == 9){ lap10.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap10.state = "created"; } if(newLapButton.lapCount == 10){ lap11.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap11.state = "created"; } if(newLapButton.lapCount == 11){ lap12.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap12.state = "created"; } newLapButton.lapCount ++; } } Rectangle{ id:resetButton width:reset.width + 9 height:reset.height + 10 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: resetIcon source: "qrc:/down.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - reset.width/2 height:parent.height-3 } SequentialAnimation{ id: resetButtonAnimation running:false NumberAnimation { target: resetButton; property: "y"; to: resetButton.y - 15; duration: 300 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y; duration: 200 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y - 8; duration: 200 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y; duration: 200 } } Text { id: reset text: "Reset" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked:{ resetButton.resetFun() } } function resetFun() { resetButtonAnimation.running=true clock.running=false timer.milliSeconds = 0; timer.seconds = 0; timer.minutes = 0; timer.hours = 0; milli.text = "00" second.text = "00" minute.text = "00" hour.text = "00" lap1.text = "" lap2.text = "" lap3.text = "" lap4.text = "" lap5.text = "" lap6.text = "" lap7.text = "" lap8.text = "" lap9.text = "" lap10.text = "" lap11.text = "" lap12.text = "" lap1.opacity = 0 lap2.opacity = 0 lap3.opacity = 0 lap4.opacity = 0 lap5.opacity = 0 lap6.opacity = 0 lap7.opacity = 0 lap8.opacity = 0 lap9.opacity = 0 lap10.opacity = 0 lap11.opacity = 0 lap12.opacity = 0 lap1.state = "" lap2.state = "" lap3.state = "" lap4.state = "" lap5.state = "" lap6.state = "" lap7.state = "" lap8.state = "" lap9.state = "" lap10.state = "" lap11.state = "" lap12.state = "" newLapButton.lapCount = 0; } } Rectangle{ id:quitButton width:quitImage.width+5 height:quitImage.height color:"transparent" Image { id: quitImage source: "qrc:/quit.png" width:startButton.height height:startButton.height anchors.centerIn:parent.Center } Image { id: quitIcon source: "qrc:/asterisk.png" opacity:0.8 anchors.bottom:quitImage.bottom anchors.horizontalCenter:quitButton.horizontalCenter width:parent.width/2 height:parent.height-6 } MouseArea{ anchors.fill:parent onClicked:{ Qt.quit() } } } } Row{ id:timer property int milliSeconds: 0 property int seconds: 0 property int minutes: 0 property int hours: 0 anchors.centerIn:parent Rectangle{ id:hourContainer width:(((parentContainer.width*20)/100)) height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: hour text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ id:minuteContainer width:(((parentContainer.width*20)/100)) height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: minute text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ id:secondContainer width:(((parentContainer.width*20)/100)) height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: second text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } Rectangle{ id:milliSecondContainer width:(((parentContainer.width*20)/100)) height:(((parentContainer.width*20)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: milli text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:26 anchors.centerIn:parent } } } Timer{ id:clock interval:50 triggeredOnStart:true onTriggered: clock.updateTime() repeat:true function updateTime() { if(timer.milliSeconds == 950) { timer.milliSeconds = 0; if(timer.seconds == 59) { timer.seconds = 0; if(timer.minutes == 59) { timer.minutes = 0; if(timer.hours == 59) clock.running=false; else timer.hours++; } else timer.minutes++; } else timer.seconds++; } else timer.milliSeconds = timer.milliSeconds+50; if(timer.milliSeconds == 0) milli.text = "000"; else milli.text = timer.milliSeconds; if(timer.seconds == 0) second.text = "00"; if(timer.seconds < 10) second.text = '0' + timer.seconds else second.text = timer.seconds; if(timer.minutes == 0) minute.text = "00"; if(timer.minutes < 10) minute.text = '0' + timer.minutes; else minute.text = timer.minutes; if(timer.hours == 0) hour.text = "00"; if(timer.hours < 10) hour.text = '0' + timer.hours; else hour.text = timer.hours; } } }
MainUI: StopWatch.qml (Best viewed in Portrait View)
import QtQuick 1.0 Rectangle { id:parentContainer width:320 height: 240 focus:true Image { id: background width:parentContainer.width height:parentContainer.height source: "background.jpg" } FontLoader{ id:digitalFont source:"trana.ttf" } Keys.onSelectPressed:{ startButton.startFunction() } Keys.onSpacePressed:{ startButton.startFunction() } Keys.onEnterPressed:{ startButton.startFunction() } Keys.onLeftPressed:{ resumeButton.resumeFun() } Keys.onRightPressed:{ stopButton.stopFunction() } Keys.onUpPressed:{ newLapButton.createNewLapRecord() } Keys.onDownPressed:{ resetButton.resetFun() } Keys.onAsteriskPressed:{ Qt.quit() } Keys.onContext2Pressed:{ Qt.quit() } Grid{ id:lapRecordView rows:4 columns:3 spacing:3 anchors.top:parent.top anchors.horizontalCenter:parent.horizontalCenter NewLapP{ id:lap1 text:"" states: [ State { name: "created" PropertyChanges { target: lap1 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap1; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap2 text:"" states: [ State { name: "created" PropertyChanges { target: lap2 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap2; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap3 text:"" states: [ State { name: "created" PropertyChanges { target: lap3 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap3; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap4 text:"" states: [ State { name: "created" PropertyChanges { target: lap4 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap4; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap5 text:"" states: [ State { name: "created" PropertyChanges { target: lap5 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap5; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap6 text:"" states: [ State { name: "created" PropertyChanges { target: lap6 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap6; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap7 text:"" states: [ State { name: "created" PropertyChanges { target: lap7 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap7; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap8 text:"" states: [ State { name: "created" PropertyChanges { target: lap8 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap8; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap9 text:"" states: [ State { name: "created" PropertyChanges { target: lap9 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap9; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap10 text:"" states: [ State { name: "created" PropertyChanges { target: lap10 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap10; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap11 text:"" states: [ State { name: "created" PropertyChanges { target: lap11 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap11; property: "opacity"; to: 1.0; duration: 200 } } ] } NewLapP{ id:lap12 text:"" states: [ State { name: "created" PropertyChanges { target: lap12 opacity:1.0 height: (parentContainer.height*8)/100 } } ] transitions: [ Transition { to:"created" NumberAnimation { target: lap12; property: "opacity"; to: 1.0; duration: 200 } } ] } } Row{ id:buttonRow spacing:3 anchors.bottom:parent.bottom anchors.bottomMargin:5 anchors.horizontalCenter:parent.horizontalCenter Rectangle{ id:startButton width:start.width + 6 height:start.height + 14 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: startIcon source: "qrc:/ok.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - start.width/2 height:parent.height-3 } SequentialAnimation{ id: startButtonAnimation running:false NumberAnimation { target: startButton; property: "y"; to: startButton.y - 15; duration: 300 } NumberAnimation { target: startButton; property: "y"; to: startButton.y; duration: 200 } NumberAnimation { target: startButton; property: "y"; to: startButton.y - 8; duration: 200 } NumberAnimation { target: startButton; property: "y"; to: startButton.y; duration: 200 } } Text { id: start text: "Start" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised color:"indigo" styleColor:"slateblue" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked: { startButton.startFunction() } } function startFunction() { clock.running = false; timer.milliSeconds = 0; timer.seconds = 0; timer.minutes = 0; timer.hours = 0; clock.running = true; startButtonAnimation.running = true } } Rectangle{ id:stopButton width:stop.width + 6 height:stop.height + 14 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: stopIcon source: "qrc:/right.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - stop.width/2 height:parent.height-3 } SequentialAnimation{ id: stopButtonAnimation running:false NumberAnimation { target: stopButton; property: "y"; to: stopButton.y - 15; duration: 300 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y; duration: 200 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y - 8; duration: 200 } NumberAnimation { target: stopButton; property: "y"; to: stopButton.y; duration: 200 } } Text { id: stop text: "Stop" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked : { stopButton.stopFunction() } } function stopFunction() { clock.running = false stopButtonAnimation.running = true } } Rectangle{ id:resumeButton width:resume.width + 6 height:resume.height + 14 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: resumeIcon source: "qrc:/left.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - resume.width/2 height:parent.height-3 } SequentialAnimation{ id: resumeButtonAnimation running:false NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y - 15; duration: 300 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y; duration: 200 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y - 8; duration: 200 } NumberAnimation { target: resumeButton; property: "y"; to: resumeButton.y; duration: 200 } } Text { id: resume text: "Resume" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked: { resumeButton.resumeFun() } } function resumeFun() { resumeButtonAnimation.running = true if(timer.milliSeconds > 0 || timer.seconds > 0 || timer.minutes > 0 || timer.hours > 0) clock.running = true; else return; } } Rectangle{ id:newLapButton property int lapCount: 0 width:newLap.width + 6 height:newLap.height + 14 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: newLapIcon source: "qrc:/up.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - newLap.width/2 height:parent.height-3 } SequentialAnimation{ id: newLapButtonAnimation running:false NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y - 15; duration: 300 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y; duration: 200 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y - 8; duration: 200 } NumberAnimation { target: newLapButton; property: "y"; to: newLapButton.y; duration: 200 } } Text { id: newLap text: "New Lap" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked:{ newLapButton.createNewLapRecord() } } function createNewLapRecord() { newLapButtonAnimation.running = true if(newLapButton.lapCount == 0){ lap1.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap1.state = "created"; } if(newLapButton.lapCount == 1){ lap2.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap2.state = "created"; } if(newLapButton.lapCount == 2){ lap3.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap3.state = "created"; } if(newLapButton.lapCount == 3){ lap4.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap4.state = "created"; } if(newLapButton.lapCount == 4){ lap5.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap5.state = "created"; } if(newLapButton.lapCount == 5){ lap6.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap6.state = "created"; } if(newLapButton.lapCount == 6){ lap7.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap7.state = "created"; } if(newLapButton.lapCount == 7){ lap8.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap8.state = "created"; } if(newLapButton.lapCount == 8){ lap9.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap9.state = "created"; } if(newLapButton.lapCount == 9){ lap10.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap10.state = "created"; } if(newLapButton.lapCount == 10){ lap11.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap11.state = "created"; } if(newLapButton.lapCount == 11){ lap12.text = hour.text + ":" + minute.text + ":" + second.text + ":" + milli.text; lap12.state = "created"; } newLapButton.lapCount ++; } } Rectangle{ id:resetButton width:reset.width + 6 height:reset.height + 14 radius:5 smooth:true gradient: Gradient{ GradientStop{color:"white"; position:0.0} GradientStop{color:"gray"; position:0.5} GradientStop{color:"white"; position:1.0} } Image { id: resetIcon source: "qrc:/down.png" opacity:0.75 anchors.horizontalCenter:parent.horizontalCenter width:parent.width - reset.width/2 height:parent.height-3 } SequentialAnimation{ id: resetButtonAnimation running:false NumberAnimation { target: resetButton; property: "y"; to: resetButton.y - 15; duration: 300 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y; duration: 200 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y - 8; duration: 200 } NumberAnimation { target: resetButton; property: "y"; to: resetButton.y; duration: 200 } } Text { id: reset text: "Reset" smooth:true font.bold:true font.italic:true font.pixelSize:(((parentContainer.width*9)/100)*50)/100 style:Text.Raised styleColor:"slateblue" color:"indigo" anchors.horizontalCenter:parent.horizontalCenter anchors.verticalCenter:parent.verticalCenter } MouseArea{ anchors.fill:parent onClicked:{ resetButton.resetFun() } } function resetFun() { resetButtonAnimation.running=true clock.running=false timer.milliSeconds = 0; timer.seconds = 0; timer.minutes = 0; timer.hours = 0; milli.text = "00" second.text = "00" minute.text = "00" hour.text = "00" lap1.text = "" lap2.text = "" lap3.text = "" lap4.text = "" lap5.text = "" lap6.text = "" lap7.text = "" lap8.text = "" lap9.text = "" lap10.text = "" lap11.text = "" lap12.text = "" lap1.opacity = 0 lap2.opacity = 0 lap3.opacity = 0 lap4.opacity = 0 lap5.opacity = 0 lap6.opacity = 0 lap7.opacity = 0 lap8.opacity = 0 lap9.opacity = 0 lap10.opacity = 0 lap11.opacity = 0 lap12.opacity = 0 lap1.state = "" lap2.state = "" lap3.state = "" lap4.state = "" lap5.state = "" lap6.state = "" lap7.state = "" lap8.state = "" lap9.state = "" lap10.state = "" lap11.state = "" lap12.state = "" newLapButton.lapCount = 0; } } Rectangle{ id:quitButton width:quitImage.width+5 height:quitImage.height color:"transparent" Image { id: quitImage source: "qrc:/quit.png" width:startButton.height height:startButton.height anchors.centerIn:parent.Center } Image { id: quitIcon source: "qrc:/asterisk.png" opacity:0.8 anchors.bottom:quitImage.bottom anchors.horizontalCenter:quitButton.horizontalCenter width:parent.width/2 height:parent.height-4 } MouseArea{ anchors.fill:parent onClicked:{ Qt.quit() } } } } Row{ id:timer property int milliSeconds: 0 property int seconds: 0 property int minutes: 0 property int hours: 0 anchors.centerIn:parent Rectangle{ id:hourContainer width:(((parentContainer.width*24)/100)) height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: hour text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ id:minuteContainer width:(((parentContainer.width*24)/100)) height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: minute text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ id:secondContainer width:(((parentContainer.width*24)/100)) height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: second text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ width:5 height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { text: ":" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } Rectangle{ id:milliSecondContainer width:(((parentContainer.width*24)/100)) height:(((parentContainer.width*24)/100)) gradient: Gradient{ GradientStop{color:"gray"; position:0} GradientStop{color:"white"; position:0.5} GradientStop{color:"gray"; position:1.0} } Text { id: milli text: "00" font.family:digitalFont.name font.bold:true smooth:true font.pixelSize:28 anchors.centerIn:parent } } } Timer{ id:clock interval:50 triggeredOnStart:true onTriggered: clock.updateTime() repeat:true function updateTime() { if(timer.milliSeconds >= 950) { timer.milliSeconds = 0; if(timer.seconds == 59) { timer.seconds = 0; if(timer.minutes == 59) { timer.minutes = 0; if(timer.hours == 59) clock.running=false; else timer.hours++; } else timer.minutes++; } else timer.seconds++; } else timer.milliSeconds = timer.milliSeconds+50; if(timer.milliSeconds == 0) milli.text = "000"; else milli.text = timer.milliSeconds; if(timer.seconds == 0) second.text = "00"; if(timer.seconds < 10) second.text = '0' + timer.seconds else second.text = timer.seconds; if(timer.minutes == 0) minute.text = "00"; if(timer.minutes < 10) minute.text = '0' + timer.minutes; else minute.text = timer.minutes; if(timer.hours == 0) hour.text = "00"; if(timer.hours < 10) hour.text = '0' + timer.hours; else hour.text = timer.hours; } } }
Used QML component for NewLap: NewLap.qml (Best viewed in Landscape view)
import Qt 4.7 Rectangle { property alias text: textItem.text width: textItem.width + 4 height: 12 border.width: 1 radius: 5 smooth: true opacity:0 gradient: Gradient { GradientStop { position: 0.0; color: "darkGray" } GradientStop { position: 0.5; color: "black" } GradientStop { position: 1.0; color: "darkGray" } } Text { id: textItem anchors.centerIn: parent smooth:true color: "white" } }
Used QML component for NewLap: NewLap.qml (Best viewed in Landscape view)
import Qt 4.7 Rectangle { property alias text: textItem.text width: textItem.width + 4 height: 18 border.width: 1 radius: 5 smooth: true opacity:0 gradient: Gradient { GradientStop { position: 0.0; color: "darkGray" } GradientStop { position: 0.5; color: "black" } GradientStop { position: 1.0; color: "darkGray" } } Text { id: textItem anchors.centerIn: parent smooth:true color: "white" } }
The Javascript code that has been used to create the application logic is just embedded into the QML code. It is a much simple program and I have done it right after my Hello World! program in QML. And thats the beauty of QML.
Additional Note:
- I have written it using the Qt version 4.7.0, but after Qt 4.7.1 you can use import QtQuick 1.0 and thats recommended too.
- Also, in this I have hardcoded the Animations for Buttons but its not necessary. You can use Behaviour, States or Transitions for the same effect with a much better & short code.
- In the main.cpp file I have calculated the screen width and height to set the application output to full screen. I will show it in the next post.
- As you can see, I have not hardcoded most of the QML items width and height and most of its been relative to the screen size. So make thing look better I have created two versions of the same above QML files. One for a Portrait view, and another for Landscape view.
- When the width of the screen is more, the QML file optimized for Landscape view is used. For example, in Nokia E Series mobiles, and vice versa.
No comments:
Post a Comment