├── Car_1.pro ├── Car_1.pro.user ├── Gauge.qml ├── README.md ├── assets ├── Car.svg ├── Dashboard.svg ├── FirstRightIcon.svg ├── FirstRightIcon_grey.svg ├── FourthRightIcon.svg ├── FourthRightIcon_red.svg ├── Info.txt ├── Light_White.svg ├── Lights.svg ├── Low beam headlights.svg ├── Low_beam_headlights_white.svg ├── Model 3.png ├── Model 3.svg ├── Parking lights.svg ├── Parking_lights_white.svg ├── Rare fog lights.svg ├── Rare_fog_lights_red.svg ├── SecondRightIcon.svg ├── SecondRightIcon_red.svg ├── Vector 1.svg ├── Vector 2.svg ├── Vector 70.svg ├── background.png ├── background.svg ├── car.png ├── fuel.svg ├── needle.svg ├── newcar.svg ├── road.svg ├── speedometer.svg ├── thirdRightIcon.svg ├── thirdRightIcon_red.svg └── tickmark.svg ├── main.cpp ├── main.qml ├── qml.qrc ├── radialbar.cpp ├── radialbar.h └── screenshots ├── Car Dashboard.gif ├── Screenshot 2023-08-12 141221.png └── screens.txt /Car_1.pro: -------------------------------------------------------------------------------- 1 | QT += quick qml 2 | 3 | # You can make your code fail to compile if it uses deprecated APIs. 4 | # In order to do so, uncomment the following line. 5 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 6 | 7 | SOURCES += \ 8 | main.cpp \ 9 | radialbar.cpp 10 | 11 | RESOURCES += qml.qrc 12 | 13 | # Additional import path used to resolve QML modules in Qt Creator's code model 14 | QML_IMPORT_PATH = 15 | 16 | # Additional import path used to resolve QML modules just for Qt Quick Designer 17 | QML_DESIGNER_IMPORT_PATH = 18 | 19 | # Default rules for deployment. 20 | qnx: target.path = /tmp/$${TARGET}/bin 21 | else: unix:!android: target.path = /opt/$${TARGET}/bin 22 | !isEmpty(target.path): INSTALLS += target 23 | 24 | HEADERS += \ 25 | radialbar.h 26 | -------------------------------------------------------------------------------- /Car_1.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {3e63a3ef-a1cd-4024-b3f8-39181fc9e94a} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | false 41 | true 42 | false 43 | 0 44 | true 45 | true 46 | 0 47 | 8 48 | true 49 | false 50 | 1 51 | true 52 | true 53 | true 54 | *.md, *.MD, Makefile 55 | false 56 | true 57 | true 58 | 59 | 60 | 61 | ProjectExplorer.Project.PluginSettings 62 | 63 | 64 | true 65 | false 66 | true 67 | true 68 | true 69 | true 70 | 71 | 72 | 0 73 | true 74 | 75 | true 76 | true 77 | Builtin.DefaultTidyAndClazy 78 | 4 79 | 80 | 81 | 82 | true 83 | 84 | 85 | true 86 | 87 | 88 | 89 | 90 | ProjectExplorer.Project.Target.0 91 | 92 | Desktop 93 | Desktop Qt 5.15.12 MSVC2019 32bit 94 | Desktop Qt 5.15.12 MSVC2019 32bit 95 | qt.qt5.51512.win32_msvc2019_kit 96 | 0 97 | 0 98 | 0 99 | 100 | 0 101 | C:\Users\ADMIN\Documents\Car_1\..\build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Debug 102 | C:/Users/ADMIN/Documents/build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Debug 103 | 104 | 105 | true 106 | QtProjectManager.QMakeBuildStep 107 | false 108 | 109 | 110 | 111 | true 112 | Qt4ProjectManager.MakeStep 113 | 114 | 2 115 | Build 116 | Build 117 | ProjectExplorer.BuildSteps.Build 118 | 119 | 120 | 121 | true 122 | Qt4ProjectManager.MakeStep 123 | clean 124 | 125 | 1 126 | Clean 127 | Clean 128 | ProjectExplorer.BuildSteps.Clean 129 | 130 | 2 131 | false 132 | 133 | false 134 | 135 | Debug 136 | Qt4ProjectManager.Qt4BuildConfiguration 137 | 2 138 | 139 | 140 | C:\Users\ADMIN\Documents\Car_1\..\build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Release 141 | C:/Users/ADMIN/Documents/build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Release 142 | 143 | 144 | true 145 | QtProjectManager.QMakeBuildStep 146 | false 147 | 148 | 149 | 150 | true 151 | Qt4ProjectManager.MakeStep 152 | 153 | 2 154 | Build 155 | Build 156 | ProjectExplorer.BuildSteps.Build 157 | 158 | 159 | 160 | true 161 | Qt4ProjectManager.MakeStep 162 | clean 163 | 164 | 1 165 | Clean 166 | Clean 167 | ProjectExplorer.BuildSteps.Clean 168 | 169 | 2 170 | false 171 | 172 | false 173 | 174 | Release 175 | Qt4ProjectManager.Qt4BuildConfiguration 176 | 0 177 | 0 178 | 179 | 180 | 0 181 | C:\Users\ADMIN\Documents\Car_1\..\build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Profile 182 | C:/Users/ADMIN/Documents/build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Profile 183 | 184 | 185 | true 186 | QtProjectManager.QMakeBuildStep 187 | false 188 | 189 | 190 | 191 | true 192 | Qt4ProjectManager.MakeStep 193 | 194 | 2 195 | Build 196 | Build 197 | ProjectExplorer.BuildSteps.Build 198 | 199 | 200 | 201 | true 202 | Qt4ProjectManager.MakeStep 203 | clean 204 | 205 | 1 206 | Clean 207 | Clean 208 | ProjectExplorer.BuildSteps.Clean 209 | 210 | 2 211 | false 212 | 213 | false 214 | 215 | Profile 216 | Qt4ProjectManager.Qt4BuildConfiguration 217 | 0 218 | 0 219 | 0 220 | 221 | 3 222 | 223 | 224 | 0 225 | Deploy 226 | Deploy 227 | ProjectExplorer.BuildSteps.Deploy 228 | 229 | 1 230 | 231 | false 232 | ProjectExplorer.DefaultDeployConfiguration 233 | 234 | 1 235 | 236 | true 237 | C:\Users\ADMIN\Downloads\qmltrash.qzt 238 | true 239 | true 240 | 241 | 2 242 | 243 | Qt4ProjectManager.Qt4RunConfiguration:C:/Users/ADMIN/Documents/Car_1/Car_1.pro 244 | C:/Users/ADMIN/Documents/Car_1/Car_1.pro 245 | false 246 | true 247 | true 248 | false 249 | true 250 | C:/Users/ADMIN/Documents/build-Car_1-Desktop_Qt_5_15_12_MSVC2019_32bit-Debug 251 | 252 | 1 253 | 254 | 255 | 256 | ProjectExplorer.Project.TargetCount 257 | 1 258 | 259 | 260 | ProjectExplorer.Project.Updater.FileVersion 261 | 22 262 | 263 | 264 | Version 265 | 22 266 | 267 | 268 | -------------------------------------------------------------------------------- /Gauge.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.7 2 | import QtQuick.Controls 2.0 3 | import QtQuick.Controls.Styles 1.4 4 | import QtQuick.Extras 1.4 5 | import QtQuick.Layouts 1.3 6 | import QtQuick.Extras.Private 1.0 7 | import QtGraphicalEffects 1.0 8 | 9 | CircularGauge { 10 | id: gauge 11 | property string speedColor: "#32D74B" 12 | function speedColorProvider(value){ 13 | if(value < 60 ){ 14 | return "#32D74B" 15 | } else if(value > 60 && value < 150){ 16 | return "yellow" 17 | }else{ 18 | return "Red" 19 | } 20 | } 21 | style: CircularGaugeStyle { 22 | labelStepSize: 10 23 | labelInset: outerRadius / 2.2 24 | tickmarkInset: outerRadius / 4.2 25 | minorTickmarkInset: outerRadius / 4.2 26 | minimumValueAngle: -144 27 | maximumValueAngle: 144 28 | 29 | background: Rectangle { 30 | implicitHeight: gauge.height 31 | implicitWidth: gauge.width 32 | color: "#1E1E1E" 33 | anchors.centerIn: parent 34 | radius: 360 35 | opacity: 0.5 36 | 37 | // Image { 38 | // anchors.fill: parent 39 | // source: "qrc:/assets/background.svg" 40 | // asynchronous: true 41 | // sourceSize { 42 | // width: width 43 | // } 44 | // } 45 | 46 | Canvas { 47 | property int value: gauge.value 48 | 49 | anchors.fill: parent 50 | onValueChanged: requestPaint() 51 | 52 | function degreesToRadians(degrees) { 53 | return degrees * (Math.PI / 180); 54 | } 55 | 56 | onPaint: { 57 | var ctx = getContext("2d"); 58 | ctx.reset(); 59 | 60 | // Define the gradient colors for the filled arc 61 | var gradientColors = [ 62 | "#32D74B", // Start color 63 | "yellow", // Middle color (you can add more colors for more segments) 64 | "red" // End color 65 | ]; 66 | 67 | // Calculate the start and end angles for the filled arc 68 | var startAngle = valueToAngle(gauge.minimumValue) - 90; 69 | var endAngle = valueToAngle(gauge.value) - 90; 70 | 71 | // Loop through the gradient colors and fill the arc segment with each color 72 | for (var i = 0; i < gradientColors.length; i++) { 73 | var gradientColor = speedColorProvider(gauge.value) 74 | speedColor = gradientColor 75 | var angle = startAngle + (endAngle - startAngle) * (i / gradientColors.length); 76 | 77 | ctx.beginPath(); 78 | ctx.lineWidth = outerRadius * 0.225; 79 | ctx.strokeStyle = gradientColor; 80 | ctx.arc(outerRadius, 81 | outerRadius, 82 | outerRadius - ctx.lineWidth / 2, 83 | degreesToRadians(angle), 84 | degreesToRadians(endAngle)); 85 | ctx.stroke(); 86 | } 87 | } 88 | 89 | } 90 | } 91 | 92 | needle: Item { 93 | visible: gauge.value.toFixed(0) > 0 94 | y: -outerRadius * 0.78 95 | height: outerRadius * 0.27 96 | Image { 97 | id: needle 98 | source: "qrc:/assets/needle.svg" 99 | height: parent.height 100 | width: height * 0.1 101 | asynchronous: true 102 | antialiasing: true 103 | } 104 | 105 | Glow { 106 | anchors.fill: needle 107 | radius: 5 108 | samples: 10 109 | color: "white" 110 | source: needle 111 | } 112 | } 113 | 114 | foreground: Item { 115 | ColumnLayout{ 116 | anchors.centerIn: parent 117 | Label{ 118 | text: gauge.value.toFixed(0) 119 | font.pixelSize: 85 120 | font.family: "Inter" 121 | color: "#01E6DE" 122 | font.bold: Font.DemiBold 123 | Layout.alignment: Qt.AlignHCenter 124 | } 125 | 126 | Label{ 127 | text: "MPH" 128 | font.pixelSize: 46 129 | font.family: "Inter" 130 | color: "#01E6DE" 131 | font.bold: Font.Normal 132 | Layout.alignment: Qt.AlignHCenter 133 | } 134 | } 135 | } 136 | 137 | tickmarkLabel: Text { 138 | font.pixelSize: Math.max(6, outerRadius * 0.05) 139 | text: styleData.value 140 | color: styleData.value <= gauge.value ? "white" : "#777776" 141 | antialiasing: true 142 | } 143 | 144 | tickmark: Image { 145 | source: "qrc:/assets/tickmark.svg" 146 | width: outerRadius * 0.018 147 | height: outerRadius * 0.15 148 | antialiasing: true 149 | asynchronous: true 150 | } 151 | 152 | minorTickmark: Rectangle { 153 | implicitWidth: outerRadius * 0.01 154 | implicitHeight: outerRadius * 0.03 155 | 156 | antialiasing: true 157 | smooth: true 158 | color: styleData.value <= gauge.value ? "white" : "darkGray" 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 👩‍💻 Aksh Singh 👩‍💻 8 |

9 | 10 |

11 | Embedded Software Engineer (QT| C++) 12 |

13 | 14 |
15 | I live in Gurugram, India and work at VVDN Technology 16 |
17 | 18 | 19 |

20 |      21 |      22 |      23 | 24 |

25 | 26 | ![Uploading Car Dashboard.gif…](https://github.com/cppqtdev/Car-Dashboard-2/blob/main/screenshots/Car%20Dashboard.gif) 27 | 28 | 29 | # Car Dashboard using Qt QML 30 | 31 | This project is a car dashboard user interface built using Qt QML. It provides a modern and intuitive interface for displaying essential information for a vehicle, such as speed, fuel level, temperature, and more. 32 | 33 | ## Table of Contents 34 | 35 | - [Introduction](#introduction) 36 | - [Features](#features) 37 | - [Screenshots](#screenshots) 38 | - [Video Demo](#video-demo) 39 | - [Prerequisites](#prerequisites) 40 | - [Getting Started](#getting-started) 41 | - [Usage](#usage) 42 | - [Contributing](#contributing) 43 | - [License](#license) 44 | - [Acknowledgments](#acknowledgments) 45 | 46 | ## Introduction 47 | 48 | The Car Dashboard project aims to create a user-friendly dashboard interface for vehicles using Qt QML. It allows users to monitor critical vehicle parameters in real-time, providing a digital representation of the traditional dashboard found in automobiles. 49 | 50 | ## Features 51 | 52 | - **Speedometer**: Displays the current speed of the vehicle in real-time. 53 | - **Fuel Gauge**: Shows the fuel level with a visual gauge. 54 | - **Temperature**: Monitors the temperature inside the vehicle. 55 | - **RPM (Revolution Per Minute)**: Indicates the engine RPM. 56 | - **Odometer**: Tracks the total distance traveled by the vehicle. 57 | - **Engine Status**: Indicates whether the engine is running or not. 58 | - **Turn Signals**: Visual indicators for left and right turn signals. 59 | - **Warning Lights**: Alerts for various vehicle conditions (e.g., low fuel, check engine). 60 | - **Customizable**: The UI is designed to be easily customizable to fit different vehicle types and styles. 61 | 62 | ## Screenshots 63 | 64 | ![Car Dashboard Screenshot](https://github.com/cppqtdev/Car-Dashboard-2/blob/main/screenshots/Screenshot%202023-08-12%20141221.png) 65 | 66 | ## Video Demo 67 | 68 | [![Car Dashboard Video Demo](https://img.youtube.com/vi/Bf660-_w5zU/0.jpg)](https://www.youtube.com/watch?v=Bf660-_w5zU) 69 | 70 | ## Prerequisites 71 | 72 | Before you begin, ensure you have met the following requirements: 73 | 74 | - Qt 5.x or higher installed on your system. 75 | - Basic knowledge of QML (Qt Quick Markup Language). 76 | 77 | ## Getting Started 78 | 79 | To get a local copy up and running, follow these simple steps: 80 | 81 | 1. Clone the repository: 82 | 83 | ```bash 84 | git clone git@github.com:cppqtdev/Car-Dashboard-2.git 85 | -------------------------------------------------------------------------------- /assets/Car.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /assets/Dashboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/FirstRightIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assets/FirstRightIcon_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/FourthRightIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/FourthRightIcon_red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/Info.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/Light_White.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/Lights.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /assets/Low beam headlights.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/Low_beam_headlights_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/Model 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cppqtdev/Qt-HMI-Display-UI/4d1959cda25454fe4f7e02e39a2bad49db5432d2/assets/Model 3.png -------------------------------------------------------------------------------- /assets/Model 3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /assets/Parking lights.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/Parking_lights_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/Rare fog lights.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/Rare_fog_lights_red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/SecondRightIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/SecondRightIcon_red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/Vector 1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /assets/Vector 2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /assets/Vector 70.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cppqtdev/Qt-HMI-Display-UI/4d1959cda25454fe4f7e02e39a2bad49db5432d2/assets/background.png -------------------------------------------------------------------------------- /assets/background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 37 | 38 | 46 | 52 | 53 | 61 | 67 | 68 | 76 | 82 | 83 | 91 | 97 | 98 | 106 | 112 | 113 | 121 | 127 | 128 | 136 | 142 | 143 | 151 | 157 | 158 | 166 | 172 | 173 | 181 | 187 | 188 | 196 | 202 | 203 | 211 | 217 | 218 | 226 | 232 | 233 | 241 | 247 | 248 | 256 | 262 | 263 | 271 | 277 | 278 | 286 | 292 | 293 | 301 | 307 | 308 | 316 | 322 | 323 | 331 | 337 | 338 | 346 | 352 | 353 | 361 | 367 | 368 | 376 | 382 | 383 | 391 | 397 | 398 | 406 | 412 | 413 | 421 | 427 | 428 | 436 | 442 | 443 | 451 | 457 | 458 | 466 | 472 | 473 | 481 | 487 | 488 | 496 | 502 | 503 | 511 | 517 | 518 | 526 | 532 | 533 | 541 | 547 | 548 | 556 | 562 | 563 | 571 | 577 | 578 | 586 | 592 | 593 | 601 | 607 | 608 | 616 | 622 | 623 | 631 | 637 | 638 | 646 | 652 | 653 | 661 | 667 | 668 | 676 | 682 | 683 | 691 | 697 | 698 | 706 | 712 | 713 | 721 | 727 | 728 | 736 | 742 | 743 | 751 | 757 | 758 | 766 | 772 | 773 | 781 | 787 | 788 | 796 | 802 | 803 | 811 | 817 | 818 | 826 | 832 | 833 | 841 | 847 | 848 | 856 | 862 | 863 | 871 | 877 | 878 | 886 | 892 | 893 | 901 | 907 | 908 | 916 | 922 | 923 | 931 | 937 | 938 | 946 | 952 | 953 | 961 | 967 | 968 | 976 | 982 | 983 | 991 | 997 | 998 | 1006 | 1012 | 1013 | 1021 | 1027 | 1028 | 1039 | 1040 | 1063 | 1065 | 1066 | 1068 | image/svg+xml 1069 | 1071 | 1072 | 1073 | 1074 | 1075 | 1080 | 1086 | 1092 | 1098 | 1099 | 1100 | -------------------------------------------------------------------------------- /assets/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cppqtdev/Qt-HMI-Display-UI/4d1959cda25454fe4f7e02e39a2bad49db5432d2/assets/car.png -------------------------------------------------------------------------------- /assets/fuel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/needle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 56 | 61 | 67 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /assets/newcar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /assets/road.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/speedometer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/thirdRightIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/thirdRightIcon_red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/tickmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 44 | 45 | 68 | 70 | 71 | 73 | image/svg+xml 74 | 76 | 77 | 78 | 79 | 80 | 85 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "radialbar.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 8 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 9 | #endif 10 | QGuiApplication app(argc, argv); 11 | 12 | QQmlApplicationEngine engine; 13 | qmlRegisterType("CustomControls", 1, 0, "RadialBar"); 14 | const QUrl url(QStringLiteral("qrc:/main.qml")); 15 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, 16 | &app, [url](QObject *obj, const QUrl &objUrl) { 17 | if (!obj && url == objUrl) 18 | QCoreApplication::exit(-1); 19 | }, Qt::QueuedConnection); 20 | engine.load(url); 21 | 22 | return app.exec(); 23 | } 24 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import CustomControls 1.0 3 | import QtQuick.Window 2.15 4 | import QtQuick.Layouts 1.3 5 | import QtQuick.Controls 2.5 6 | import "./" 7 | ApplicationWindow { 8 | width: 1920 9 | height: 960 10 | visible: true 11 | title: qsTr("Car DashBoard") 12 | color: "#1E1E1E" 13 | visibility: "FullScreen" 14 | property int nextSpeed: 60 15 | 16 | function generateRandom(maxLimit = 70){ 17 | let rand = Math.random() * maxLimit; 18 | rand = Math.floor(rand); 19 | return rand; 20 | } 21 | 22 | function speedColor(value){ 23 | if(value < 60 ){ 24 | return "green" 25 | } else if(value > 60 && value < 150){ 26 | return "yellow" 27 | }else{ 28 | return "Red" 29 | } 30 | } 31 | 32 | Timer { 33 | interval: 500 34 | running: true 35 | repeat: true 36 | onTriggered:{ 37 | 38 | currentTime.text = Qt.formatDateTime(new Date(), "hh:mm") 39 | } 40 | } 41 | 42 | Timer{ 43 | repeat: true 44 | interval: 3000 45 | running: true 46 | onTriggered: { 47 | nextSpeed = generateRandom() 48 | } 49 | } 50 | 51 | Shortcut { 52 | sequence: "Ctrl+Q" 53 | context: Qt.ApplicationShortcut 54 | onActivated: Qt.quit() 55 | } 56 | 57 | 58 | Image { 59 | id: dashboard 60 | width: parent.width 61 | height: parent.height 62 | anchors.centerIn: parent 63 | source: "qrc:/assets/Dashboard.svg" 64 | 65 | /* 66 | Top Bar Of Screen 67 | */ 68 | 69 | Image { 70 | id: topBar 71 | width: 1357 72 | source: "qrc:/assets/Vector 70.svg" 73 | 74 | anchors{ 75 | top: parent.top 76 | topMargin: 26.50 77 | horizontalCenter: parent.horizontalCenter 78 | } 79 | 80 | Image { 81 | id: headLight 82 | property bool indicator: false 83 | width: 42.5 84 | height: 38.25 85 | anchors{ 86 | top: parent.top 87 | topMargin: 25 88 | leftMargin: 230 89 | left: parent.left 90 | } 91 | source: indicator ? "qrc:/assets/Low beam headlights.svg" : "qrc:/assets/Low_beam_headlights_white.svg" 92 | Behavior on indicator { NumberAnimation { duration: 300 }} 93 | MouseArea{ 94 | anchors.fill: parent 95 | onClicked: { 96 | headLight.indicator = !headLight.indicator 97 | } 98 | } 99 | } 100 | 101 | Label{ 102 | id: currentTime 103 | text: Qt.formatDateTime(new Date(), "hh:mm") 104 | font.pixelSize: 32 105 | font.family: "Inter" 106 | font.bold: Font.DemiBold 107 | color: "#FFFFFF" 108 | anchors.top: parent.top 109 | anchors.topMargin: 25 110 | anchors.horizontalCenter: parent.horizontalCenter 111 | } 112 | 113 | Label{ 114 | id: currentDate 115 | text: Qt.formatDateTime(new Date(), "dd/MM/yyyy") 116 | font.pixelSize: 32 117 | font.family: "Inter" 118 | font.bold: Font.DemiBold 119 | color: "#FFFFFF" 120 | anchors.right: parent.right 121 | anchors.rightMargin: 230 122 | anchors.top: parent.top 123 | anchors.topMargin: 25 124 | } 125 | } 126 | 127 | 128 | 129 | /* 130 | Speed Label 131 | */ 132 | 133 | // Label{ 134 | // id:speedLabel 135 | // text: "68" 136 | // font.pixelSize: 134 137 | // font.family: "Inter" 138 | // color: "#01E6DE" 139 | // font.bold: Font.DemiBold 140 | // anchors.top: parent.top 141 | // anchors.topMargin:Math.floor(parent.height * 0.35) 142 | // anchors.horizontalCenter: parent.horizontalCenter 143 | // } 144 | Gauge { 145 | id: speedLabel 146 | width: 450 147 | height: 450 148 | property bool accelerating 149 | value: accelerating ? maximumValue : 0 150 | maximumValue: 250 151 | 152 | anchors.top: parent.top 153 | anchors.topMargin:Math.floor(parent.height * 0.25) 154 | anchors.horizontalCenter: parent.horizontalCenter 155 | 156 | Component.onCompleted: forceActiveFocus() 157 | 158 | Behavior on value { NumberAnimation { duration: 1000 }} 159 | 160 | Keys.onSpacePressed: accelerating = true 161 | Keys.onReleased: { 162 | if (event.key === Qt.Key_Space) { 163 | accelerating = false; 164 | event.accepted = true; 165 | }else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { 166 | radialBar.accelerating = false; 167 | event.accepted = true; 168 | } 169 | } 170 | 171 | Keys.onEnterPressed: radialBar.accelerating = true 172 | Keys.onReturnPressed: radialBar.accelerating = true 173 | } 174 | 175 | // Label{ 176 | // text: "MPH" 177 | // font.pixelSize: 46 178 | // font.family: "Inter" 179 | // color: "#01E6DE" 180 | // font.bold: Font.Normal 181 | // anchors.top:speedLabel.bottom 182 | // anchors.horizontalCenter: parent.horizontalCenter 183 | // } 184 | 185 | 186 | /* 187 | Speed Limit Label 188 | */ 189 | 190 | Rectangle{ 191 | id:speedLimit 192 | width: 130 193 | height: 130 194 | radius: height/2 195 | color: "#D9D9D9" 196 | border.color: speedColor(maxSpeedlabel.text) 197 | border.width: 10 198 | 199 | anchors.horizontalCenter: parent.horizontalCenter 200 | anchors.bottom: parent.bottom 201 | anchors.bottomMargin: 50 202 | 203 | Label{ 204 | id:maxSpeedlabel 205 | text: getRandomInt(150, speedLabel.maximumValue).toFixed(0) 206 | font.pixelSize: 45 207 | font.family: "Inter" 208 | font.bold: Font.Bold 209 | color: "#01E6DE" 210 | anchors.centerIn: parent 211 | 212 | function getRandomInt(min, max) { 213 | return Math.floor(Math.random() * (max - min + 1)) + min; 214 | } 215 | } 216 | } 217 | 218 | Image { 219 | anchors{ 220 | bottom: car.top 221 | bottomMargin: 30 222 | horizontalCenter:car.horizontalCenter 223 | } 224 | source: "qrc:/assets/Model 3.png" 225 | } 226 | 227 | 228 | Image { 229 | id:car 230 | anchors{ 231 | bottom: speedLimit.top 232 | bottomMargin: 30 233 | horizontalCenter:speedLimit.horizontalCenter 234 | } 235 | source: "qrc:/assets/Car.svg" 236 | } 237 | 238 | // IMGonline.com.ua ==> Compress Image With 239 | 240 | 241 | /* 242 | Left Road 243 | */ 244 | 245 | Image { 246 | id: leftRoad 247 | width: 127 248 | height: 397 249 | anchors{ 250 | left: speedLimit.left 251 | leftMargin: 100 252 | bottom: parent.bottom 253 | bottomMargin: 26.50 254 | } 255 | 256 | source: "qrc:/assets/Vector 2.svg" 257 | } 258 | 259 | RowLayout{ 260 | spacing: 20 261 | 262 | anchors{ 263 | left: parent.left 264 | leftMargin: 250 265 | bottom: parent.bottom 266 | bottomMargin: 26.50 + 65 267 | } 268 | 269 | RowLayout{ 270 | spacing: 3 271 | Label{ 272 | text: "100.6" 273 | font.pixelSize: 32 274 | font.family: "Inter" 275 | font.bold: Font.Normal 276 | font.capitalization: Font.AllUppercase 277 | color: "#FFFFFF" 278 | } 279 | 280 | Label{ 281 | text: "°F" 282 | font.pixelSize: 32 283 | font.family: "Inter" 284 | font.bold: Font.Normal 285 | font.capitalization: Font.AllUppercase 286 | opacity: 0.2 287 | color: "#FFFFFF" 288 | } 289 | } 290 | 291 | RowLayout{ 292 | spacing: 1 293 | Layout.topMargin: 10 294 | Rectangle{ 295 | width: 20 296 | height: 15 297 | color: speedLabel.value.toFixed(0) > 31.25 ? speedLabel.speedColor : "#01E6DC" 298 | } 299 | Rectangle{ 300 | width: 20 301 | height: 15 302 | color: speedLabel.value.toFixed(0) > 62.5 ? speedLabel.speedColor : "#01E6DC" 303 | } 304 | Rectangle{ 305 | width: 20 306 | height: 15 307 | color: speedLabel.value.toFixed(0) > 93.75 ? speedLabel.speedColor : "#01E6DC" 308 | } 309 | Rectangle{ 310 | width: 20 311 | height: 15 312 | color: speedLabel.value.toFixed(0) > 125.25 ? speedLabel.speedColor : "#01E6DC" 313 | } 314 | Rectangle{ 315 | width: 20 316 | height: 15 317 | color: speedLabel.value.toFixed(0) > 156.5 ? speedLabel.speedColor : "#01E6DC" 318 | } 319 | Rectangle{ 320 | width: 20 321 | height: 15 322 | color: speedLabel.value.toFixed(0) > 187.75 ? speedLabel.speedColor : "#01E6DC" 323 | } 324 | Rectangle{ 325 | width: 20 326 | height: 15 327 | color: speedLabel.value.toFixed(0) > 219 ? speedLabel.speedColor : "#01E6DC" 328 | } 329 | } 330 | 331 | Label{ 332 | text: speedLabel.value.toFixed(0) + " MPH " 333 | font.pixelSize: 32 334 | font.family: "Inter" 335 | font.bold: Font.Normal 336 | font.capitalization: Font.AllUppercase 337 | color: "#FFFFFF" 338 | } 339 | } 340 | 341 | /* 342 | Right Road 343 | */ 344 | 345 | Image { 346 | id: rightRoad 347 | width: 127 348 | height: 397 349 | anchors{ 350 | right: speedLimit.right 351 | rightMargin: 100 352 | bottom: parent.bottom 353 | bottomMargin: 26.50 354 | } 355 | 356 | source: "qrc:/assets/Vector 1.svg" 357 | } 358 | 359 | /* 360 | Right Side gear 361 | */ 362 | 363 | RowLayout{ 364 | spacing: 20 365 | anchors{ 366 | right: parent.right 367 | rightMargin: 350 368 | bottom: parent.bottom 369 | bottomMargin: 26.50 + 65 370 | } 371 | 372 | Label{ 373 | text: "Ready" 374 | font.pixelSize: 32 375 | font.family: "Inter" 376 | font.bold: Font.Normal 377 | font.capitalization: Font.AllUppercase 378 | color: "#32D74B" 379 | } 380 | 381 | Label{ 382 | text: "P" 383 | font.pixelSize: 32 384 | font.family: "Inter" 385 | font.bold: Font.Normal 386 | font.capitalization: Font.AllUppercase 387 | color: "#FFFFFF" 388 | } 389 | 390 | Label{ 391 | text: "R" 392 | font.pixelSize: 32 393 | font.family: "Inter" 394 | font.bold: Font.Normal 395 | font.capitalization: Font.AllUppercase 396 | opacity: 0.2 397 | color: "#FFFFFF" 398 | } 399 | Label{ 400 | text: "N" 401 | font.pixelSize: 32 402 | font.family: "Inter" 403 | font.bold: Font.Normal 404 | font.capitalization: Font.AllUppercase 405 | opacity: 0.2 406 | color: "#FFFFFF" 407 | } 408 | Label{ 409 | text: "D" 410 | font.pixelSize: 32 411 | font.family: "Inter" 412 | font.bold: Font.Normal 413 | font.capitalization: Font.AllUppercase 414 | opacity: 0.2 415 | color: "#FFFFFF" 416 | } 417 | } 418 | 419 | /*Left Side Icons*/ 420 | Image { 421 | id:forthLeftIndicator 422 | property bool parkingLightOn: true 423 | width: 72 424 | height: 62 425 | anchors{ 426 | left: parent.left 427 | leftMargin: 175 428 | bottom: thirdLeftIndicator.top 429 | bottomMargin: 25 430 | } 431 | Behavior on parkingLightOn { NumberAnimation { duration: 300 }} 432 | source: parkingLightOn ? "qrc:/assets/Parking lights.svg" : "qrc:/assets/Parking_lights_white.svg" 433 | MouseArea{ 434 | anchors.fill: parent 435 | onClicked: { 436 | forthLeftIndicator.parkingLightOn = !forthLeftIndicator.parkingLightOn 437 | } 438 | } 439 | } 440 | 441 | Image { 442 | id:thirdLeftIndicator 443 | property bool lightOn: true 444 | width: 52 445 | height: 70.2 446 | anchors{ 447 | left: parent.left 448 | leftMargin: 145 449 | bottom: secondLeftIndicator.top 450 | bottomMargin: 25 451 | } 452 | source: lightOn ? "qrc:/assets/Lights.svg" : "qrc:/assets/Light_White.svg" 453 | Behavior on lightOn { NumberAnimation { duration: 300 }} 454 | MouseArea{ 455 | anchors.fill: parent 456 | onClicked: { 457 | thirdLeftIndicator.lightOn = !thirdLeftIndicator.lightOn 458 | } 459 | } 460 | } 461 | 462 | Image { 463 | id:secondLeftIndicator 464 | property bool headLightOn: true 465 | width: 51 466 | height: 51 467 | anchors{ 468 | left: parent.left 469 | leftMargin: 125 470 | bottom: firstLeftIndicator.top 471 | bottomMargin: 30 472 | } 473 | Behavior on headLightOn { NumberAnimation { duration: 300 }} 474 | source:headLightOn ? "qrc:/assets/Low beam headlights.svg" : "qrc:/assets/Low_beam_headlights_white.svg" 475 | 476 | MouseArea{ 477 | anchors.fill: parent 478 | onClicked: { 479 | secondLeftIndicator.headLightOn = !secondLeftIndicator.headLightOn 480 | } 481 | } 482 | } 483 | 484 | Image { 485 | id:firstLeftIndicator 486 | property bool rareLightOn: false 487 | width: 51 488 | height: 51 489 | anchors{ 490 | left: parent.left 491 | leftMargin: 100 492 | verticalCenter: speedLabel.verticalCenter 493 | } 494 | source: rareLightOn ? "qrc:/assets/Rare_fog_lights_red.svg" : "qrc:/assets/Rare fog lights.svg" 495 | Behavior on rareLightOn { NumberAnimation { duration: 300 }} 496 | MouseArea{ 497 | anchors.fill: parent 498 | onClicked: { 499 | firstLeftIndicator.rareLightOn = !firstLeftIndicator.rareLightOn 500 | } 501 | } 502 | } 503 | 504 | /*Right Side Icons*/ 505 | 506 | Image { 507 | id:forthRightIndicator 508 | property bool indicator: true 509 | width: 56.83 510 | height: 36.17 511 | anchors{ 512 | right: parent.right 513 | rightMargin: 195 514 | bottom: thirdRightIndicator.top 515 | bottomMargin: 50 516 | } 517 | source: indicator ? "qrc:/assets/FourthRightIcon.svg" : "qrc:/assets/FourthRightIcon_red.svg" 518 | Behavior on indicator { NumberAnimation { duration: 300 }} 519 | MouseArea{ 520 | anchors.fill: parent 521 | onClicked: { 522 | forthRightIndicator.indicator = !forthRightIndicator.indicator 523 | } 524 | } 525 | } 526 | 527 | Image { 528 | id:thirdRightIndicator 529 | property bool indicator: true 530 | width: 56.83 531 | height: 36.17 532 | anchors{ 533 | right: parent.right 534 | rightMargin: 155 535 | bottom: secondRightIndicator.top 536 | bottomMargin: 50 537 | } 538 | source: indicator ? "qrc:/assets/thirdRightIcon.svg" : "qrc:/assets/thirdRightIcon_red.svg" 539 | Behavior on indicator { NumberAnimation { duration: 300 }} 540 | MouseArea{ 541 | anchors.fill: parent 542 | onClicked: { 543 | thirdRightIndicator.indicator = !thirdRightIndicator.indicator 544 | } 545 | } 546 | } 547 | 548 | Image { 549 | id:secondRightIndicator 550 | property bool indicator: true 551 | width: 56.83 552 | height: 36.17 553 | anchors{ 554 | right: parent.right 555 | rightMargin: 125 556 | bottom: firstRightIndicator.top 557 | bottomMargin: 50 558 | } 559 | source: indicator ? "qrc:/assets/SecondRightIcon.svg" : "qrc:/assets/SecondRightIcon_red.svg" 560 | Behavior on indicator { NumberAnimation { duration: 300 }} 561 | MouseArea{ 562 | anchors.fill: parent 563 | onClicked: { 564 | secondRightIndicator.indicator = !secondRightIndicator.indicator 565 | } 566 | } 567 | } 568 | 569 | Image { 570 | id:firstRightIndicator 571 | property bool sheetBelt: true 572 | width: 36 573 | height: 45 574 | anchors{ 575 | right: parent.right 576 | rightMargin: 100 577 | verticalCenter: speedLabel.verticalCenter 578 | } 579 | source: sheetBelt ? "qrc:/assets/FirstRightIcon.svg" : "qrc:/assets/FirstRightIcon_grey.svg" 580 | Behavior on sheetBelt { NumberAnimation { duration: 300 }} 581 | MouseArea{ 582 | anchors.fill: parent 583 | onClicked: { 584 | firstRightIndicator.sheetBelt = !firstRightIndicator.sheetBelt 585 | } 586 | } 587 | } 588 | 589 | // Progress Bar 590 | RadialBar { 591 | id:radialBar 592 | anchors{ 593 | verticalCenter: parent.verticalCenter 594 | left: parent.left 595 | leftMargin: parent.width / 6 596 | } 597 | 598 | width: 338 599 | height: 338 600 | penStyle: Qt.RoundCap 601 | dialType: RadialBar.NoDial 602 | progressColor: "#01E4E0" 603 | backgroundColor: "transparent" 604 | dialWidth: 17 605 | startAngle: 270 606 | spanAngle: 3.6 * value 607 | minValue: 0 608 | maxValue: 100 609 | value: accelerating ? maxValue : 65 610 | textFont { 611 | family: "inter" 612 | italic: false 613 | bold: Font.Medium 614 | pixelSize: 60 615 | } 616 | showText: false 617 | suffixText: "" 618 | textColor: "#FFFFFF" 619 | 620 | property bool accelerating 621 | Behavior on value { NumberAnimation { duration: 1000 }} 622 | 623 | ColumnLayout{ 624 | anchors.centerIn: parent 625 | Label{ 626 | text: radialBar.value.toFixed(0) + "%" 627 | font.pixelSize: 65 628 | font.family: "Inter" 629 | font.bold: Font.Normal 630 | color: "#FFFFFF" 631 | Layout.alignment: Qt.AlignHCenter 632 | } 633 | 634 | Label{ 635 | text: "Battery charge" 636 | font.pixelSize: 28 637 | font.family: "Inter" 638 | font.bold: Font.Normal 639 | opacity: 0.8 640 | color: "#FFFFFF" 641 | Layout.alignment: Qt.AlignHCenter 642 | } 643 | } 644 | } 645 | 646 | ColumnLayout{ 647 | spacing: 40 648 | 649 | anchors{ 650 | verticalCenter: parent.verticalCenter 651 | right: parent.right 652 | rightMargin: parent.width / 6 653 | } 654 | 655 | RowLayout{ 656 | spacing: 30 657 | Image { 658 | width: 72 659 | height: 50 660 | source: "qrc:/assets/road.svg" 661 | } 662 | 663 | ColumnLayout{ 664 | Label{ 665 | text: "188 KM" 666 | font.pixelSize: 30 667 | font.family: "Inter" 668 | font.bold: Font.Normal 669 | opacity: 0.8 670 | color: "#FFFFFF" 671 | } 672 | Label{ 673 | text: "Distance" 674 | font.pixelSize: 20 675 | font.family: "Inter" 676 | font.bold: Font.Normal 677 | opacity: 0.8 678 | color: "#FFFFFF" 679 | } 680 | } 681 | } 682 | RowLayout{ 683 | spacing: 30 684 | Image { 685 | width: 72 686 | height: 78 687 | source: "qrc:/assets/fuel.svg" 688 | } 689 | 690 | ColumnLayout{ 691 | Label{ 692 | text: "34 mpg" 693 | font.pixelSize: 30 694 | font.family: "Inter" 695 | font.bold: Font.Normal 696 | opacity: 0.8 697 | color: "#FFFFFF" 698 | } 699 | Label{ 700 | text: "Avg. Fuel Usage" 701 | font.pixelSize: 20 702 | font.family: "Inter" 703 | font.bold: Font.Normal 704 | opacity: 0.8 705 | color: "#FFFFFF" 706 | } 707 | } 708 | } 709 | RowLayout{ 710 | spacing: 30 711 | Image { 712 | width: 72 713 | height: 72 714 | source: "qrc:/assets/speedometer.svg" 715 | } 716 | 717 | ColumnLayout{ 718 | Label{ 719 | text: "78 mph" 720 | font.pixelSize: 30 721 | font.family: "Inter" 722 | font.bold: Font.Normal 723 | opacity: 0.8 724 | color: "#FFFFFF" 725 | } 726 | Label{ 727 | text: "Avg. Speed" 728 | font.pixelSize: 20 729 | font.family: "Inter" 730 | font.bold: Font.Normal 731 | opacity: 0.8 732 | color: "#FFFFFF" 733 | } 734 | } 735 | } 736 | } 737 | } 738 | } 739 | -------------------------------------------------------------------------------- /qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | assets/Dashboard.svg 5 | assets/Vector 70.svg 6 | assets/Low beam headlights.svg 7 | assets/Vector 1.svg 8 | assets/Vector 2.svg 9 | assets/FirstRightIcon.svg 10 | assets/FourthRightIcon.svg 11 | assets/Lights.svg 12 | assets/Parking lights.svg 13 | assets/Rare fog lights.svg 14 | assets/SecondRightIcon.svg 15 | assets/thirdRightIcon.svg 16 | assets/car.png 17 | assets/fuel.svg 18 | assets/road.svg 19 | assets/speedometer.svg 20 | Gauge.qml 21 | assets/background.png 22 | assets/background.svg 23 | assets/needle.svg 24 | assets/tickmark.svg 25 | assets/newcar.svg 26 | assets/Car.svg 27 | assets/Model 3.svg 28 | assets/Model 3.png 29 | assets/Light_White.svg 30 | assets/Parking_lights_white.svg 31 | assets/Low_beam_headlights_white.svg 32 | assets/Rare_fog_lights_red.svg 33 | assets/FirstRightIcon_grey.svg 34 | assets/SecondRightIcon_red.svg 35 | assets/thirdRightIcon_red.svg 36 | assets/FourthRightIcon_red.svg 37 | 38 | 39 | -------------------------------------------------------------------------------- /radialbar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "radialbar.h" 3 | 4 | RadialBar::RadialBar(QQuickItem *parent) 5 | : QQuickPaintedItem(parent), 6 | m_Size(200), 7 | m_StartAngle(40), 8 | m_SpanAngle(280), 9 | m_MinValue(0), 10 | m_MaxValue(100), 11 | m_Value(50), 12 | m_DialWidth(15), 13 | m_BackgroundColor(Qt::transparent), 14 | m_DialColor(QColor(80,80,80)), 15 | m_ProgressColor(QColor(135,26,5)), 16 | m_TextColor(QColor(0, 0, 0)), 17 | m_SuffixText(""), 18 | m_ShowText(true), 19 | m_PenStyle(Qt::FlatCap), 20 | m_DialType(DialType::MinToMax) 21 | { 22 | setWidth(200); 23 | setHeight(200); 24 | setSmooth(true); 25 | setAntialiasing(true); 26 | } 27 | 28 | void RadialBar::paint(QPainter *painter) 29 | { 30 | double startAngle; 31 | double spanAngle; 32 | qreal size = qMin(this->width(), this->height()); 33 | setWidth(size); 34 | setHeight(size); 35 | QRectF rect = this->boundingRect(); 36 | painter->setRenderHint(QPainter::Antialiasing); 37 | QPen pen = painter->pen(); 38 | pen.setCapStyle(m_PenStyle); 39 | 40 | startAngle = -90 - m_StartAngle; 41 | if(FullDial != m_DialType) 42 | { 43 | spanAngle = 0 - m_SpanAngle; 44 | } 45 | else 46 | { 47 | spanAngle = -360; 48 | } 49 | 50 | //Draw outer dial 51 | painter->save(); 52 | pen.setWidth(m_DialWidth); 53 | pen.setColor(m_DialColor); 54 | painter->setPen(pen); 55 | qreal offset = m_DialWidth / 2; 56 | if(m_DialType == MinToMax) 57 | { 58 | painter->drawArc(rect.adjusted(offset, offset, -offset, -offset), startAngle * 16, spanAngle * 16); 59 | } 60 | else if(m_DialType == FullDial) 61 | { 62 | painter->drawArc(rect.adjusted(offset, offset, -offset, -offset), -90 * 16, -360 * 16); 63 | } 64 | else 65 | { 66 | //do not draw dial 67 | } 68 | painter->restore(); 69 | 70 | //Draw background 71 | painter->save(); 72 | painter->setBrush(m_BackgroundColor); 73 | painter->setPen(m_BackgroundColor); 74 | qreal inner = offset * 2; 75 | painter->drawEllipse(rect.adjusted(inner, inner, -inner, -inner)); 76 | painter->restore(); 77 | 78 | //Draw progress text with suffix 79 | painter->save(); 80 | painter->setFont(m_TextFont); 81 | pen.setColor(m_TextColor); 82 | painter->setPen(pen); 83 | if(m_ShowText) 84 | { 85 | painter->drawText(rect.adjusted(offset, offset, -offset, -offset), Qt::AlignCenter,QString::number(m_Value) + m_SuffixText); 86 | } 87 | else 88 | { 89 | painter->drawText(rect.adjusted(offset, offset, -offset, -offset), Qt::AlignCenter, m_SuffixText); 90 | } 91 | painter->restore(); 92 | 93 | //Draw progress bar 94 | painter->save(); 95 | pen.setWidth(m_DialWidth); 96 | pen.setColor(m_ProgressColor); 97 | qreal valueAngle = ((m_Value - m_MinValue)/(m_MaxValue - m_MinValue)) * spanAngle; //Map value to angle range 98 | painter->setPen(pen); 99 | painter->drawArc(rect.adjusted(offset, offset, -offset, -offset), startAngle * 16, valueAngle * 16); 100 | painter->restore(); 101 | } 102 | 103 | void RadialBar::setSize(qreal size) 104 | { 105 | if(m_Size == size) 106 | return; 107 | m_Size = size; 108 | emit sizeChanged(); 109 | } 110 | 111 | void RadialBar::setStartAngle(qreal angle) 112 | { 113 | if(m_StartAngle == angle) 114 | return; 115 | m_StartAngle = angle; 116 | emit startAngleChanged(); 117 | } 118 | 119 | void RadialBar::setSpanAngle(qreal angle) 120 | { 121 | if(m_SpanAngle == angle) 122 | return; 123 | m_SpanAngle = angle; 124 | emit spanAngleChanged(); 125 | } 126 | 127 | void RadialBar::setMinValue(qreal value) 128 | { 129 | if(m_MinValue == value) 130 | return; 131 | m_MinValue = value; 132 | emit minValueChanged(); 133 | } 134 | 135 | void RadialBar::setMaxValue(qreal value) 136 | { 137 | if(m_MaxValue == value) 138 | return; 139 | m_MaxValue = value; 140 | emit maxValueChanged(); 141 | } 142 | 143 | void RadialBar::setValue(qreal value) 144 | { 145 | if(m_Value == value) 146 | return; 147 | m_Value = value; 148 | update(); //update the radialbar 149 | emit valueChanged(); 150 | } 151 | 152 | void RadialBar::setDialWidth(qreal width) 153 | { 154 | if(m_DialWidth == width) 155 | return; 156 | m_DialWidth = width; 157 | emit dialWidthChanged(); 158 | } 159 | 160 | void RadialBar::setBackgroundColor(QColor color) 161 | { 162 | if(m_BackgroundColor == color) 163 | return; 164 | m_BackgroundColor = color; 165 | emit backgroundColorChanged(); 166 | } 167 | 168 | void RadialBar::setForegroundColor(QColor color) 169 | { 170 | if(m_DialColor == color) 171 | return; 172 | m_DialColor = color; 173 | emit foregroundColorChanged(); 174 | } 175 | 176 | void RadialBar::setProgressColor(QColor color) 177 | { 178 | if(m_ProgressColor == color) 179 | return; 180 | m_ProgressColor = color; 181 | emit progressColorChanged(); 182 | } 183 | 184 | void RadialBar::setTextColor(QColor color) 185 | { 186 | if(m_TextColor == color) 187 | return; 188 | m_TextColor = color; 189 | emit textColorChanged(); 190 | } 191 | 192 | void RadialBar::setSuffixText(QString text) 193 | { 194 | if(m_SuffixText == text) 195 | return; 196 | m_SuffixText = text; 197 | emit suffixTextChanged(); 198 | } 199 | 200 | void RadialBar::setShowText(bool show) 201 | { 202 | if(m_ShowText == show) 203 | return; 204 | m_ShowText = show; 205 | } 206 | 207 | void RadialBar::setPenStyle(Qt::PenCapStyle style) 208 | { 209 | if(m_PenStyle == style) 210 | return; 211 | m_PenStyle = style; 212 | emit penStyleChanged(); 213 | } 214 | 215 | void RadialBar::setDialType(RadialBar::DialType type) 216 | { 217 | if(m_DialType == type) 218 | return; 219 | m_DialType = type; 220 | emit dialTypeChanged(); 221 | } 222 | 223 | void RadialBar::setTextFont(QFont font) 224 | { 225 | if(m_TextFont == font) 226 | return; 227 | m_TextFont = font; 228 | emit textFontChanged(); 229 | } 230 | -------------------------------------------------------------------------------- /radialbar.h: -------------------------------------------------------------------------------- 1 | #ifndef RADIALBAR_H 2 | #define RADIALBAR_H 3 | 4 | #include 5 | 6 | class RadialBar : public QQuickPaintedItem 7 | { 8 | Q_OBJECT 9 | 10 | Q_PROPERTY(qreal size READ getSize WRITE setSize NOTIFY sizeChanged) 11 | Q_PROPERTY(qreal startAngle READ getStartAngle WRITE setStartAngle NOTIFY startAngleChanged) 12 | Q_PROPERTY(qreal spanAngle READ getSpanAngle WRITE setSpanAngle NOTIFY spanAngleChanged) 13 | Q_PROPERTY(qreal minValue READ getMinValue WRITE setMinValue NOTIFY minValueChanged) 14 | Q_PROPERTY(qreal maxValue READ getMaxValue WRITE setMaxValue NOTIFY maxValueChanged) 15 | Q_PROPERTY(qreal value READ getValue WRITE setValue NOTIFY valueChanged) 16 | Q_PROPERTY(int dialWidth READ getDialWidth WRITE setDialWidth NOTIFY dialWidthChanged) 17 | Q_PROPERTY(QColor backgroundColor READ getBackgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged) 18 | Q_PROPERTY(QColor foregroundColor READ getForegroundColor WRITE setForegroundColor NOTIFY foregroundColorChanged) 19 | Q_PROPERTY(QColor progressColor READ getProgressColor WRITE setProgressColor NOTIFY progressColorChanged) 20 | Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor NOTIFY textColorChanged) 21 | Q_PROPERTY(QString suffixText READ getSuffixText WRITE setSuffixText NOTIFY suffixTextChanged) 22 | Q_PROPERTY(bool showText READ isShowText WRITE setShowText) 23 | Q_PROPERTY(Qt::PenCapStyle penStyle READ getPenStyle WRITE setPenStyle NOTIFY penStyleChanged) 24 | Q_PROPERTY(DialType dialType READ getDialType WRITE setDialType NOTIFY dialTypeChanged) 25 | Q_PROPERTY(QFont textFont READ getTextFont WRITE setTextFont NOTIFY textFontChanged) 26 | 27 | public: 28 | RadialBar(QQuickItem *parent = 0); 29 | void paint(QPainter *painter); 30 | 31 | enum DialType { 32 | FullDial, 33 | MinToMax, 34 | NoDial 35 | }; 36 | Q_ENUM(DialType) 37 | 38 | qreal getSize() {return m_Size;} 39 | qreal getStartAngle() {return m_StartAngle;} 40 | qreal getSpanAngle() {return m_SpanAngle;} 41 | qreal getMinValue() {return m_MinValue;} 42 | qreal getMaxValue() {return m_MaxValue;} 43 | qreal getValue() {return m_Value;} 44 | int getDialWidth() {return m_DialWidth;} 45 | QColor getBackgroundColor() {return m_BackgroundColor;} 46 | QColor getForegroundColor() {return m_DialColor;} 47 | QColor getProgressColor() {return m_ProgressColor;} 48 | QColor getTextColor() {return m_TextColor;} 49 | QString getSuffixText() {return m_SuffixText;} 50 | bool isShowText() {return m_ShowText;} 51 | Qt::PenCapStyle getPenStyle() {return m_PenStyle;} 52 | DialType getDialType() {return m_DialType;} 53 | QFont getTextFont() {return m_TextFont;} 54 | 55 | void setSize(qreal size); 56 | void setStartAngle(qreal angle); 57 | void setSpanAngle(qreal angle); 58 | void setMinValue(qreal value); 59 | void setMaxValue(qreal value); 60 | void setValue(qreal value); 61 | void setDialWidth(qreal width); 62 | void setBackgroundColor(QColor color); 63 | void setForegroundColor(QColor color); 64 | void setProgressColor(QColor color); 65 | void setTextColor(QColor color); 66 | void setSuffixText(QString text); 67 | void setShowText(bool show); 68 | void setPenStyle(Qt::PenCapStyle style); 69 | void setDialType(DialType type); 70 | void setTextFont(QFont font); 71 | 72 | signals: 73 | void sizeChanged(); 74 | void startAngleChanged(); 75 | void spanAngleChanged(); 76 | void minValueChanged(); 77 | void maxValueChanged(); 78 | void valueChanged(); 79 | void dialWidthChanged(); 80 | void backgroundColorChanged(); 81 | void foregroundColorChanged(); 82 | void progressColorChanged(); 83 | void textColorChanged(); 84 | void suffixTextChanged(); 85 | void penStyleChanged(); 86 | void dialTypeChanged(); 87 | void textFontChanged(); 88 | 89 | private: 90 | qreal m_Size; 91 | qreal m_StartAngle; 92 | qreal m_SpanAngle; 93 | qreal m_MinValue; 94 | qreal m_MaxValue; 95 | qreal m_Value; 96 | int m_DialWidth; 97 | QColor m_BackgroundColor; 98 | QColor m_DialColor; 99 | QColor m_ProgressColor; 100 | QColor m_TextColor; 101 | QString m_SuffixText; 102 | bool m_ShowText; 103 | Qt::PenCapStyle m_PenStyle; 104 | DialType m_DialType; 105 | QFont m_TextFont; 106 | }; 107 | 108 | #endif // RADIALBAR_H 109 | -------------------------------------------------------------------------------- /screenshots/Car Dashboard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cppqtdev/Qt-HMI-Display-UI/4d1959cda25454fe4f7e02e39a2bad49db5432d2/screenshots/Car Dashboard.gif -------------------------------------------------------------------------------- /screenshots/Screenshot 2023-08-12 141221.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cppqtdev/Qt-HMI-Display-UI/4d1959cda25454fe4f7e02e39a2bad49db5432d2/screenshots/Screenshot 2023-08-12 141221.png -------------------------------------------------------------------------------- /screenshots/screens.txt: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------