├── Dashboard.qml ├── Fuel.qml ├── FuelNeedle.qml ├── Gear.qml ├── Info.qml ├── README.md ├── Speed.qml ├── SpeedNeedle.qml ├── Turn.qml ├── dashboard.qmlproject └── main.qml /Dashboard.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_dashboard 5 | 6 | //to creating data for demonstration purpose 7 | property int count: 0 8 | property int randNum: 0 9 | Timer { 10 | id: id_timer 11 | repeat: true 12 | interval: 1000 13 | running: true 14 | 15 | onTriggered: { 16 | if(id_gear.value == 6) id_gear.value = 0; 17 | else id_gear.value++; 18 | 19 | if(count % 5 == 0){ 20 | if(id_speed.value == 0) id_speed.value = 280 21 | else id_speed.value = 0 22 | 23 | if(id_info.fuelValue == 0) id_info.fuelValue = 4 24 | else id_info.fuelValue = 0 25 | } 26 | count++; 27 | 28 | if(count % 2 == 0){ 29 | id_turnLeft.isActive = true 30 | id_turnRight.isActive = false 31 | }else{ 32 | id_turnLeft.isActive = false 33 | id_turnRight.isActive = true 34 | } 35 | } 36 | } 37 | 38 | Rectangle { 39 | id: id_speedArea 40 | 41 | anchors { 42 | horizontalCenter: parent.horizontalCenter 43 | } 44 | width: parent.width * 0.4 45 | height: width 46 | color: "black" 47 | radius: width/2 48 | z: 1 49 | 50 | Speed { 51 | id: id_speed 52 | anchors.fill: id_speedArea 53 | anchors.margins: id_speedArea.width * 0.025 54 | } 55 | } 56 | 57 | Rectangle { 58 | id: id_gearArea 59 | 60 | anchors { 61 | bottom: id_speedArea.bottom 62 | } 63 | x: parent.width / 20 64 | width: parent.width * 0.35 65 | height: width 66 | color: "black" 67 | radius: width/2 68 | 69 | Gear { 70 | id: id_gear 71 | anchors.fill: id_gearArea 72 | anchors.margins: id_gearArea.width * 0.025 73 | } 74 | } 75 | 76 | Rectangle { 77 | id: id_infoArea 78 | 79 | anchors { 80 | bottom: id_speedArea.bottom 81 | } 82 | x: parent.width - parent.width / 2.5 83 | width: parent.width * 0.35 84 | height: width 85 | color: "black" 86 | radius: width/2 87 | 88 | Info { 89 | id: id_info 90 | anchors.fill: id_infoArea 91 | anchors.margins: id_infoArea.width * 0.025 92 | } 93 | } 94 | 95 | Rectangle { 96 | anchors { 97 | bottom: id_speedArea.bottom 98 | left: id_gearArea.horizontalCenter 99 | right: id_infoArea.horizontalCenter 100 | } 101 | height: id_gearArea.width / 2 102 | color: "black" 103 | z: -1 104 | } 105 | 106 | Turn { 107 | id: id_turnLeft 108 | 109 | anchors { 110 | right: id_gearArea.right 111 | rightMargin: id_gearArea.height * 0.04 112 | bottom: id_gearArea.bottom 113 | bottomMargin: id_gearArea.height * 0.01 114 | } 115 | width: id_gearArea.width / 5.5 116 | height: id_gearArea.height / 8.2 117 | 118 | isActive: false 119 | } 120 | 121 | Turn { 122 | id: id_turnRight 123 | 124 | anchors { 125 | left: id_infoArea.left 126 | leftMargin: id_infoArea.height * 0.04 127 | bottom: id_infoArea.bottom 128 | bottomMargin: id_infoArea.height * 0.01 129 | } 130 | width: id_infoArea.width / 5.5 131 | height: id_infoArea.height / 8.2 132 | transformOrigin: Item.Center 133 | rotation: 180 134 | 135 | isActive: true 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Fuel.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | 6 | property int value: 0 7 | 8 | Rectangle { 9 | id: id_fuel 10 | 11 | property int numberIndexs: 5 12 | 13 | anchors.centerIn: parent 14 | height: Math.min(id_root.width, id_root.height) 15 | width: height 16 | radius: width/2 17 | color: "black" 18 | border.color: "light green" 19 | border.width: id_fuel.height * 0.02 20 | 21 | Canvas { 22 | id:canvas 23 | anchors.fill: parent 24 | contextType: "2d" 25 | antialiasing: true 26 | 27 | onPaint: { 28 | var context = canvas.getContext('2d'); 29 | 30 | context.strokeStyle = "red"; 31 | context.lineWidth = id_fuel.height * 0.05; 32 | context.beginPath(); 33 | context.arc(id_fuel.height / 2, id_fuel.height / 2, id_fuel.height / 2 - id_fuel.height * 0.07, Math.PI, Math.PI * 1.25, false); 34 | context.stroke(); 35 | 36 | context.strokeStyle = "blue"; 37 | context.lineWidth = id_fuel.height * 0.05; 38 | context.beginPath(); 39 | context.arc(id_fuel.height / 2, id_fuel.height / 2, id_fuel.height / 2 - id_fuel.height * 0.07, Math.PI * 1.25, Math.PI * 2.0, false); 40 | context.stroke(); 41 | } 42 | } 43 | 44 | Repeater { 45 | model: id_fuel.numberIndexs 46 | 47 | Item { 48 | height: id_fuel.height/2 49 | transformOrigin: Item.Bottom 50 | rotation: index * 45 + 270 51 | x: id_fuel.width/2 52 | 53 | Rectangle { 54 | height: index % 2 == 0 ? id_fuel.height * 0.15 : id_fuel.height * 0.1 55 | width: height / 2 56 | color: index == 0 ? "red" : "light green" 57 | antialiasing: true 58 | anchors.horizontalCenter: parent.horizontalCenter 59 | anchors.top: parent.top 60 | anchors.topMargin: id_fuel.height * 0.03 61 | } 62 | } 63 | } 64 | 65 | Text { 66 | anchors { 67 | top: parent.verticalCenter 68 | left: parent.left 69 | topMargin: id_fuel.height * 0.01 70 | leftMargin: id_fuel.height * 0.06 71 | } 72 | text: "E" 73 | color: "red" 74 | font.pixelSize: id_fuel.height * 0.15 75 | font.family: "Impact" 76 | } 77 | 78 | Text { 79 | anchors { 80 | top: parent.verticalCenter 81 | right: parent.right 82 | topMargin: id_fuel.height * 0.01 83 | rightMargin: id_fuel.height * 0.06 84 | } 85 | text: "F" 86 | color: "light green" 87 | font.pixelSize: id_fuel.height * 0.15 88 | font.family: "Impact" 89 | } 90 | } 91 | 92 | Rectangle { 93 | id: id_center 94 | 95 | anchors.centerIn: parent 96 | height: id_fuel.height * 0.1 97 | width: height 98 | radius: width/2 99 | color: "light green" 100 | } 101 | 102 | FuelNeedle { 103 | id: id_fuelNeedle 104 | anchors { 105 | top: id_fuel.top 106 | bottom: id_fuel.bottom 107 | horizontalCenter: parent.horizontalCenter 108 | } 109 | value: id_root.value 110 | startAngle: 270 111 | angleLength: 45 112 | } 113 | 114 | Rectangle { 115 | id: id_fuelIcon1 116 | 117 | anchors { 118 | horizontalCenter: id_root.horizontalCenter 119 | } 120 | y: id_fuel.height * 0.25 121 | height: id_fuel.height * 0.075 122 | width: height 123 | color: "transparent" 124 | border.color: "light green" 125 | border.width: id_fuel.height * 0.01 126 | } 127 | 128 | Rectangle { 129 | id: id_fuelIcon2 130 | 131 | anchors { 132 | horizontalCenter: id_root.horizontalCenter 133 | top: id_fuelIcon1.bottom 134 | } 135 | height: id_fuel.height * 0.075 136 | width: height 137 | color: "light green" 138 | border.color: "light green" 139 | border.width: id_fuel.height * 0.01 140 | } 141 | 142 | Rectangle { 143 | id: id_fuelIcon3 144 | 145 | anchors { 146 | horizontalCenter: id_root.horizontalCenter 147 | top: id_fuelIcon2.bottom 148 | topMargin: id_fuel.height * 0.009 149 | } 150 | height: id_fuel.height * 0.02 151 | width: height * 5 152 | color: "light green" 153 | border.color: "light green" 154 | border.width: id_fuel.height * 0.01 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /FuelNeedle.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | 6 | property int value: 0 7 | property int startAngle : 0 8 | property double angleLength: 0 9 | 10 | Rectangle { 11 | width: id_root.height * 0.02 12 | height: id_root.height * 0.45 13 | color: "light green" 14 | anchors { 15 | horizontalCenter: id_root.horizontalCenter 16 | } 17 | antialiasing: true 18 | y: id_root.height * 0.05 19 | } 20 | 21 | rotation: value * angleLength + startAngle 22 | 23 | antialiasing: true 24 | 25 | Behavior on rotation { 26 | SmoothedAnimation { velocity: 50 } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Gear.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | 6 | property int value: 0 7 | 8 | Rectangle { 9 | id: id_gear 10 | 11 | anchors.centerIn: parent 12 | height: Math.min(id_root.width, id_root.height) 13 | width: height 14 | radius: width/2 15 | color: "black" 16 | border.color: "light green" 17 | border.width: id_gear.height * 0.02 18 | 19 | Repeater { 20 | model: 7 21 | 22 | Item { 23 | height: id_gear.height/2 24 | transformOrigin: Item.Bottom 25 | rotation: index * 30 + 200 26 | x: id_gear.width/2 27 | 28 | Rectangle { 29 | height: id_gear.height * 0.12 + index * id_gear.height * 0.01 30 | width: height 31 | color: index == value ? "light green" : "grey" 32 | radius: width/2 33 | antialiasing: true 34 | anchors.horizontalCenter: parent.horizontalCenter 35 | anchors.top: parent.top 36 | anchors.topMargin: id_gear.height * 0.05 37 | 38 | Text { 39 | anchors.centerIn: parent 40 | color: "black" 41 | text: index 42 | font.pixelSize: parent.height * 0.5 43 | font.family: "Comic Sans MS" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | Text { 51 | anchors.centerIn: parent 52 | text: "Gear\nPosition" 53 | color: "light green" 54 | font.pixelSize: id_gear.height * 0.1 55 | font.family: "Comic Sans MS" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Info.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | 6 | property var currentDate: new Date() 7 | property int fuelValue: 0 8 | 9 | Timer { 10 | id: timer 11 | repeat: true 12 | interval: 1000 13 | running: true 14 | 15 | onTriggered: id_root.currentDate = new Date() 16 | } 17 | 18 | Rectangle { 19 | id: id_info 20 | 21 | anchors.centerIn: parent 22 | height: Math.min(id_root.width, id_root.height) 23 | width: height 24 | radius: width/2 25 | color: "black" 26 | border.color: "light green" 27 | border.width: id_info.height * 0.02 28 | 29 | Text { 30 | id: id_date 31 | anchors { 32 | horizontalCenter: id_info.horizontalCenter 33 | top: id_info.top 34 | topMargin: id_info.height * 0.07 35 | } 36 | color: "light green" 37 | font.pixelSize: id_info.height * 0.1 38 | font.family: "Impact" 39 | text: currentDate.getDate() + "/" + currentDate.getMonth() + "/" + currentDate.getFullYear() 40 | } 41 | 42 | Text { 43 | id: id_clock 44 | anchors { 45 | horizontalCenter: id_info.horizontalCenter 46 | top: id_date.bottom 47 | topMargin: id_info.height * 0.01 48 | } 49 | color: "light green" 50 | font.pixelSize: id_info.height * 0.1 51 | font.family: "Impact" 52 | text: currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds() 53 | } 54 | 55 | Fuel { 56 | x: id_info.height * 0.3 57 | y: id_info.height * 0.35 58 | width: id_info.height * 0.55 59 | height: width 60 | z: 1 61 | value: id_root.fuelValue 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![picture](https://user-images.githubusercontent.com/24628660/31160602-b4213152-a8fb-11e7-88c4-710ce563465f.png) 2 | 3 | This application is written by QML language(Qt 5.8) 4 | 5 | It show up some functions of Dashboard such as: Speed, Gear, Fuel, Date, Time 6 | 7 | In this example, we use some controls of Qt QML such as: Item, Rectangle, Timer, Repeater, Text, Canvas, Smoothed Animation 8 | 9 | Demonstration video at: 10 | https://www.youtube.com/watch?v=45kHwLI0njk 11 | 12 | Implementaion guideline video at: 13 | https://www.youtube.com/watch?v=tfVxhL99c3s&t=272s 14 | -------------------------------------------------------------------------------- /Speed.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | property int value: 0 6 | 7 | Rectangle { 8 | id: id_speed 9 | 10 | property int numberIndexs: 15 11 | property int startAngle: 234 12 | property int angleLength: 18 13 | property int maxSpeed: 280 14 | 15 | anchors.centerIn: parent 16 | height: Math.min(id_root.width, id_root.height) 17 | width: height 18 | radius: width/2 19 | color: "black" 20 | border.color: "light green" 21 | border.width: id_speed.height * 0.02 22 | 23 | Canvas { 24 | id:canvas 25 | anchors.fill: parent 26 | contextType: "2d" 27 | rotation: 145 28 | antialiasing: true 29 | 30 | onPaint: { 31 | var context = canvas.getContext('2d'); 32 | context.strokeStyle = "blue"; 33 | context.lineWidth = id_speed.height * 0.05 / 2; 34 | context.beginPath(); 35 | context.arc(id_speed.height / 2, id_speed.height / 2, id_speed.height / 2 - id_speed.height * 0.05, 0, Math.PI * 1.1, false); 36 | context.stroke(); 37 | 38 | context.strokeStyle = "red"; 39 | context.lineWidth = id_speed.height * 0.05 / 2; 40 | context.beginPath(); 41 | context.arc(id_speed.height / 2, id_speed.height / 2, id_speed.height / 2 - id_speed.height * 0.05, Math.PI * 1.1, Math.PI * 1.4, false); 42 | context.stroke(); 43 | } 44 | } 45 | 46 | Repeater { 47 | model: id_speed.numberIndexs 48 | 49 | Item { 50 | height: id_speed.height/2 51 | transformOrigin: Item.Bottom 52 | rotation: index * id_speed.angleLength + id_speed.startAngle 53 | x: id_speed.width/2 54 | 55 | Rectangle { 56 | height: id_speed.height * 0.05 57 | width: height / 2 58 | color: "light green" 59 | antialiasing: true 60 | anchors.horizontalCenter: parent.horizontalCenter 61 | anchors.top: parent.top 62 | anchors.topMargin: id_speed.height * 0.03 63 | } 64 | 65 | Text { 66 | anchors { 67 | horizontalCenter: parent.horizontalCenter 68 | } 69 | x: 0 70 | y: id_speed.height * 0.09 71 | color: "light green" 72 | rotation: 360 - (index * id_speed.angleLength + id_speed.startAngle) 73 | text: index * (id_speed.maxSpeed / (id_speed.numberIndexs - 1)) 74 | font.pixelSize: id_speed.height * 0.05 75 | font.family: "Comic Sans MS" 76 | } 77 | } 78 | } 79 | } 80 | 81 | Rectangle { 82 | id: id_center 83 | 84 | anchors.centerIn: parent 85 | height: id_speed.height*0.1 86 | width: height 87 | radius: width/2 88 | color: "light green" 89 | } 90 | 91 | Text { 92 | anchors { 93 | horizontalCenter: parent.horizontalCenter 94 | top: id_speed.verticalCenter 95 | topMargin: id_speed.height * 0.1 96 | } 97 | text: "Speed\n km/h" 98 | color: "light green" 99 | font.pixelSize: id_speed.height * 0.1 100 | font.family: "Comic Sans MS" 101 | } 102 | 103 | SpeedNeedle { 104 | id: id_speedNeedle 105 | anchors { 106 | top: id_speed.top 107 | bottom: id_speed.bottom 108 | horizontalCenter: parent.horizontalCenter 109 | } 110 | value: id_root.value 111 | startAngle: id_speed.startAngle 112 | angleLength: id_speed.angleLength / (id_speed.maxSpeed / (id_speed.numberIndexs - 1)) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /SpeedNeedle.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | property int value: 0 6 | property int startAngle : 0 7 | property double angleLength: 0 8 | property int maxSpeed: 0 9 | 10 | Rectangle { 11 | width: id_root.height * 0.02 12 | height: id_root.height * 0.45 13 | color: "light green" 14 | anchors { 15 | horizontalCenter: id_root.horizontalCenter 16 | } 17 | antialiasing: true 18 | y: id_root.height * 0.05 19 | } 20 | 21 | rotation: value * angleLength + startAngle 22 | 23 | antialiasing: true 24 | 25 | Behavior on rotation { 26 | SmoothedAnimation { velocity: 50 } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Turn.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Item { 4 | id: id_root 5 | 6 | property bool isActive: false 7 | 8 | onIsActiveChanged: { 9 | canvas.requestPaint() 10 | } 11 | 12 | Canvas { 13 | id: canvas 14 | anchors.fill: parent 15 | contextType: "2d" 16 | antialiasing: true 17 | 18 | onPaint: { 19 | var context = canvas.getContext('2d'); 20 | 21 | if(isActive) context.fillStyle = "light green" 22 | else context.fillStyle = "grey" 23 | 24 | context.beginPath() 25 | context.moveTo(0, id_root.height / 2) 26 | context.lineTo(id_root.width / 3, 0) 27 | context.lineTo(id_root.width / 3, id_root.height) 28 | context.lineTo(0, id_root.height / 2) 29 | context.closePath() 30 | 31 | context.fill() 32 | } 33 | } 34 | 35 | Rectangle { 36 | id: id_rec 37 | 38 | anchors { 39 | left: id_root.left 40 | leftMargin: id_root.width / 3.1 41 | verticalCenter: id_root.verticalCenter 42 | right: id_root.right 43 | } 44 | height: id_root.height * 0.5 45 | color: isActive ? "light green" : "grey" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dashboard.qmlproject: -------------------------------------------------------------------------------- 1 | /* File generated by Qt Creator */ 2 | 3 | import QmlProject 1.1 4 | 5 | Project { 6 | mainFile: "main.qml" 7 | 8 | /* Include .qml, .js, and image files from current directory and subdirectories */ 9 | QmlFiles { 10 | directory: "." 11 | } 12 | JavaScriptFiles { 13 | directory: "." 14 | } 15 | ImageFiles { 16 | directory: "." 17 | } 18 | /* List of plugin directories passed to QML runtime */ 19 | // importPaths: [ "../exampleplugin" ] 20 | } 21 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | 3 | Dashboard { 4 | width: 720 5 | height: 480 6 | } 7 | --------------------------------------------------------------------------------