├── Dashboard_qml.zip └── Dashboard_qml ├── images ├── chip.ico ├── dash.png ├── dash1.png ├── svg_images │ ├── avion.png │ ├── chip.png │ ├── cil-chart-line.svg │ ├── cil-touch-app.svg │ ├── cil-exposure.svg │ ├── cil-equalizer.svg │ ├── cil-speedometer.svg │ ├── cil-sun.svg │ ├── cil-fire.svg │ ├── minimize_icon.svg │ ├── maximize_icon.svg │ ├── close_icon.svg │ ├── open_icon.svg │ ├── restore_icon.svg │ ├── menu_icon.svg │ ├── save_icon.svg │ ├── resize_icon.svg │ ├── home_icon.svg │ ├── settings_icon.svg │ ├── icon_app_top.svg │ └── 051-cpu.svg └── png_images │ ├── flag.svg │ ├── oil.svg │ ├── atom.svg │ ├── engine coolant.svg │ ├── parking lights.svg │ ├── spark plug.svg │ ├── engine.svg │ ├── seat_belt.svg │ ├── circle_red_1.svg │ ├── circle_orange_1.svg │ ├── circle_yellow_1.svg │ ├── circle_black.svg │ └── circle_green_1.svg ├── arduino_code ├── Arduino-Mega-Pinout.jpg ├── arduino-mega-pinout-diagram.png └── arduino_code.ino ├── qml ├── controls │ ├── CTabButton.qml │ ├── CCheckBox.qml │ ├── CustomTextField.qml │ ├── CustomButton.qml │ ├── ToggleButton.qml │ ├── CLabel.qml │ ├── MultiButton.qml │ ├── TopBarButton.qml │ ├── CSlider.qml │ ├── LeftMenuBtn.qml │ ├── CustomSlider.qml │ ├── __Slider.qml │ ├── CustomSwitch.qml │ └── _ItemParam.qml └── pages │ ├── iniPage.qml │ ├── chartPage.qml │ ├── bonusPage.qml │ ├── settingsPage.qml │ ├── inputPage.qml │ └── outputPage.qml └── GUI_QML_main.pyw /Dashboard_qml.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml.zip -------------------------------------------------------------------------------- /Dashboard_qml/images/chip.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/images/chip.ico -------------------------------------------------------------------------------- /Dashboard_qml/images/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/images/dash.png -------------------------------------------------------------------------------- /Dashboard_qml/images/dash1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/images/dash1.png -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/avion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/images/svg_images/avion.png -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/chip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/images/svg_images/chip.png -------------------------------------------------------------------------------- /Dashboard_qml/arduino_code/Arduino-Mega-Pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/arduino_code/Arduino-Mega-Pinout.jpg -------------------------------------------------------------------------------- /Dashboard_qml/arduino_code/arduino-mega-pinout-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jahirg/QML_Dashbord/HEAD/Dashboard_qml/arduino_code/arduino-mega-pinout-diagram.png -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-chart-line.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-touch-app.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-exposure.svg: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CTabButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.14 2 | import QtQuick.Controls 2.14 3 | 4 | TabButton { 5 | id: control 6 | padding: 0 7 | 8 | contentItem: Text { 9 | text: control.text 10 | font: control.font 11 | color: "#fefefe" 12 | horizontalAlignment: Text.AlignHCenter 13 | verticalAlignment: Text.AlignVCenter 14 | elide: Text.ElideRight 15 | } 16 | 17 | background: Rectangle { 18 | implicitWidth: 100 19 | implicitHeight: 40 20 | color: control.checked ? "#303030" : "#353637" 21 | } 22 | 23 | Rectangle { 24 | width: parent.width 25 | height: 3 26 | anchors.bottom: parent.bottom 27 | visible: control.checked 28 | color: "beige" 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-equalizer.svg: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/iniPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Window 2.15 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Controls.Styles 1.4 5 | import QtQuick.Extras 1.4 6 | import QtQuick.Extras.Private 1.0 7 | 8 | 9 | Item { 10 | 11 | Rectangle { 12 | id: rectangle 13 | color: "#2c313c" 14 | anchors.fill: parent 15 | 16 | //////////////////////////////////////////////////////////////////// 17 | 18 | 19 | Image { 20 | id: image 21 | source: "../../images/dash1.png" 22 | height:parent.height 23 | width:parent.width 24 | //fillMode: Image.PreserveAspectCrop 25 | //Layout.fillHeight: true 26 | //Layout.fillWidth: true 27 | } 28 | 29 | //////////////////////////////////////////////////////////////////// 30 | 31 | } 32 | Connections{ 33 | target: backend 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CCheckBox.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.12 2 | import QtQuick.Controls 2.12 3 | 4 | CheckBox { 5 | id: control 6 | leftPadding: 0 7 | 8 | indicator: Rectangle { 9 | implicitWidth: 20 10 | implicitHeight: 20 11 | x: control.leftPadding 12 | y: parent.height / 2 - height / 2 13 | radius: 3 14 | border.color: "#505050" 15 | color: "transparent" 16 | 17 | Rectangle { 18 | width: 12 19 | height: 12 20 | anchors.centerIn: parent 21 | radius: 3 22 | color: "#303030" 23 | visible: control.checked 24 | } 25 | } 26 | 27 | contentItem: Text { 28 | text: control.text 29 | font: control.font 30 | opacity: enabled ? 1.0 : 0.3 31 | color: "#fefefe" 32 | verticalAlignment: Text.AlignVCenter 33 | leftPadding: control.indicator.width + control.spacing 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-speedometer.svg: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CustomTextField.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtGraphicalEffects 1.15 4 | 5 | TextField { 6 | id: textField 7 | 8 | // Custom Properties 9 | property color colorDefault: "#282c34" 10 | property color colorOnFocus: "#242831" 11 | property color colorMouseOver: "#2B2F38" 12 | 13 | QtObject{ 14 | id: internal 15 | 16 | property var dynamicColor: if(textField.focus){ 17 | textField.hovered ? colorOnFocus : colorDefault 18 | }else{ 19 | textField.hovered ? colorMouseOver : colorDefault 20 | } 21 | } 22 | 23 | implicitWidth: 300 24 | implicitHeight: 40 25 | placeholderText: qsTr("Type something") 26 | color: "#ffffff" 27 | background: Rectangle { 28 | color: internal.dynamicColor 29 | radius: 10 30 | } 31 | 32 | selectByMouse: true 33 | selectedTextColor: "#FFFFFF" 34 | selectionColor: "#ff007f" 35 | placeholderTextColor: "#81848c" 36 | } 37 | 38 | /*##^## 39 | Designer { 40 | D{i:0;autoSize:true;height:40;width:640} 41 | } 42 | ##^##*/ 43 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CustomButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtGraphicalEffects 1.15 4 | 5 | Button { 6 | id: button 7 | 8 | // Custom Properties 9 | property color colorDefault: "#4891d9" 10 | property color colorMouseOver: "#55AAFF" 11 | property color colorPressed: "#3F7EBD" 12 | 13 | QtObject{ 14 | id: internal 15 | 16 | property var dynamicColor: if(button.down){ 17 | button.down ? colorPressed : colorDefault 18 | }else{ 19 | button.hovered ? colorMouseOver : colorDefault 20 | } 21 | } 22 | 23 | text: qsTr("Button") 24 | contentItem: Item{ 25 | Text { 26 | id: name 27 | text: button.text 28 | font: button.font 29 | color: "#ffffff" 30 | anchors.verticalCenter: parent.verticalCenter 31 | anchors.horizontalCenter: parent.horizontalCenter 32 | } 33 | } 34 | 35 | background: Rectangle{ 36 | color: internal.dynamicColor 37 | radius: 10 38 | } 39 | } 40 | /*##^## 41 | Designer { 42 | D{i:0;autoSize:true;height:40;width:200} 43 | } 44 | ##^##*/ 45 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/ToggleButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtGraphicalEffects 1.15 4 | 5 | Button{ 6 | id: btnToggle 7 | hoverEnabled: true 8 | 9 | // CUSTOM PROPERTIES 10 | property url btnIconSource: "../../images/svg_images/menu_icon.svg" 11 | property color btnColorDefault: "#1c1d20" 12 | property color btnColorMouseOver: "#23272E" 13 | property color btnColorClicked: "#0080b0" 14 | 15 | QtObject{ 16 | id: internal 17 | // MOUSE OVER AND CLICK CHANGE COLOR 18 | property var dynamicColor: if(btnToggle.down){ 19 | btnToggle.down ? btnColorClicked : btnColorDefault 20 | } else { 21 | btnToggle.hovered ? btnColorMouseOver : btnColorDefault 22 | } 23 | } 24 | 25 | implicitWidth: 60 26 | implicitHeight: 60 27 | 28 | background: Rectangle{ 29 | id: bgBtn 30 | color: internal.dynamicColor 31 | radius: 10 32 | Image { 33 | id: iconBtn 34 | source: btnIconSource 35 | anchors.verticalCenter: parent.verticalCenter 36 | anchors.horizontalCenter: parent.horizontalCenter 37 | height: 25 38 | width: 25 39 | fillMode: Image.PreserveAspectFit 40 | visible: false 41 | } 42 | ColorOverlay{ 43 | anchors.fill: iconBtn 44 | source: iconBtn 45 | color: "#e0e0e0" 46 | antialiasing: false 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-sun.svg: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CLabel.qml: -------------------------------------------------------------------------------- 1 | /************************************************************************************* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2021 Arun Pk 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | ************************************************************************************/ 24 | 25 | import QtQuick 2.14 26 | import QtQuick.Controls 2.14 27 | 28 | Label { 29 | color: "#FEFEFE" 30 | } 31 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/cil-fire.svg: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/MultiButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtQuick.Controls 1.0 3 | import QtQuick.Controls.Styles 1.0 4 | 5 | Item { 6 | id: button 7 | 8 | property string text: "Option: " 9 | property variant items: ["first"] 10 | property int currentSelection: 0 11 | signal selectionChanged(variant selection) 12 | 13 | signal clicked 14 | 15 | implicitWidth: 120 //buttonText.implicitWidth + 5 16 | implicitHeight: buttonText.implicitHeight + 10 17 | 18 | Button { 19 | id: buttonText 20 | width: parent.width 21 | height: parent.height 22 | 23 | style: ButtonStyle { 24 | background: Rectangle { 25 | radius: 10 26 | color: "#202020" 27 | border.color: "#a0a0a0" 28 | border.width :2 29 | } 30 | 31 | label: Component { 32 | Text { 33 | text: button.text + button.items[currentSelection] 34 | clip: true 35 | font.bold : true 36 | font.pointSize: 10 37 | color: "#e0e0e0" 38 | wrapMode: Text.WordWrap 39 | verticalAlignment: Text.AlignVCenter 40 | horizontalAlignment: Text.AlignHCenter 41 | anchors.fill: parent 42 | } 43 | } 44 | } 45 | onClicked: { 46 | currentSelection = (currentSelection + 1) % items.length; 47 | selectionChanged(button.items[currentSelection]); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/TopBarButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtGraphicalEffects 1.15 4 | 5 | Button{ 6 | id: btnTopBar 7 | // CUSTOM PROPERTIES 8 | property url btnIconSource: "../../images/svg_images/minimize_icon.svg" 9 | property color btnColorDefault: "#1c1d20" 10 | property color btnColorMouseOver: "#23f72E" 11 | property color btnColorClicked: "#00a1f1" 12 | 13 | QtObject{ 14 | id: internal 15 | // MOUSE OVER AND CLICK CHANGE COLOR 16 | property var dynamicColor: 17 | if(btnTopBar.down){ 18 | btnTopBar.down ? btnColorClicked : btnColorDefault 19 | } else { 20 | btnTopBar.hovered ? btnColorMouseOver : btnColorDefault 21 | } 22 | } 23 | 24 | width: 35 25 | height: 35 26 | 27 | background: Rectangle{ 28 | id: bgBtn 29 | color: internal.dynamicColor 30 | radius: 5 31 | anchors.left: parent.left 32 | anchors.right: parent.right 33 | anchors.top: parent.top 34 | anchors.bottom: parent.bottom 35 | 36 | anchors.leftMargin: 4 37 | anchors.rightMargin: 4 38 | anchors.topMargin: 4 39 | anchors.bottomMargin: 4 40 | 41 | 42 | Image { 43 | id: iconBtn 44 | source: btnIconSource 45 | anchors.verticalCenter: parent.verticalCenter 46 | anchors.horizontalCenter: parent.horizontalCenter 47 | height: 24 48 | width: 24 49 | visible: false 50 | fillMode: Image.PreserveAspectFit 51 | antialiasing: false 52 | } 53 | 54 | ColorOverlay{ 55 | anchors.fill: iconBtn 56 | source: iconBtn 57 | color: "#000000" 58 | antialiasing: false 59 | } 60 | } 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/minimize_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 56 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/flag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/maximize_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 56 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/close_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 56 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/open_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 56 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/oil.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 50 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/restore_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 55 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/menu_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 76 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/save_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 62 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CSlider.qml: -------------------------------------------------------------------------------- 1 | /************************************************************************************* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2021 Arun Pk 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | ************************************************************************************/ 24 | 25 | import QtQuick 2.14 26 | import QtQuick.Controls 2.14 27 | 28 | Slider { 29 | id: control 30 | stepSize: 1 31 | property string bgcolor : "#21be2b" 32 | 33 | background: Rectangle { 34 | x: control.leftPadding 35 | y: control.topPadding + control.availableHeight / 2 - height / 2 36 | implicitWidth: 200 37 | implicitHeight: 4 38 | width: control.availableWidth 39 | height: implicitHeight 40 | radius: 2 41 | color: "#c0c0c0" 42 | 43 | Rectangle { 44 | width: control.visualPosition * parent.width 45 | height: parent.height 46 | //color: "#21be2b" 47 | color : bgcolor 48 | radius: 2 49 | } 50 | } 51 | 52 | handle: Rectangle { 53 | x: control.leftPadding + control.visualPosition * (control.availableWidth - width) 54 | y: control.topPadding + control.availableHeight / 2 - height / 2 55 | implicitWidth: 26 56 | implicitHeight: 26 57 | radius: 13 58 | color: control.pressed ? "#f0f0f0" : "#f6f6f6" 59 | border.color: "#bdbebf" 60 | Label { 61 | anchors.centerIn: parent 62 | text: Number(control.value).toFixed() 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/resize_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 72 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/atom.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/engine coolant.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 58 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/parking lights.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 60 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/home_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 63 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/spark plug.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/LeftMenuBtn.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Controls 2.15 3 | import QtGraphicalEffects 1.15 4 | 5 | Button{ 6 | id: btnLeftMenu 7 | text: qsTr("Left Menu Text") 8 | 9 | // CUSTOM PROPERTIES 10 | property url btnIconSource: "../../images/svg_images/home_icon.svg" 11 | property color btnColorDefault: "#1c1d20" 12 | property color btnColorMouseOver: "#005280" 13 | property color btnColorClicked: "#00a1f1" 14 | property int iconWidth: 32 15 | property int iconHeight: 32 16 | property color activeMenuColor: "#1c1d20" 17 | property color activeMenuColorRight: "#55aaff" 18 | property bool isActiveMenu: false 19 | 20 | property color imgColorActived: "#23272E" 21 | property color imgColorDefault: "#00a1f1" 22 | implicitWidth: 250 23 | implicitHeight: 60 24 | ////////////////// 25 | // QtObject{ 26 | // id: internalImg 27 | // // ICON COLOR ACTIVE 28 | // property var dynamicColorImg: 29 | // if(btnLeftMenu.down){ 30 | // btnLeftMenu.down ? btnColorClicked : btnColorDefault 31 | // } else { 32 | // btnLeftMenu.hovered ? btnColorMouseOver : btnColorDefault 33 | // } 34 | // } 35 | ///////////////////// 36 | 37 | QtObject{ 38 | id: internal 39 | // MOUSE OVER AND CLICK CHANGE COLOR 40 | property var dynamicColor: 41 | if(btnLeftMenu.down){ 42 | btnLeftMenu.down ? btnColorClicked : btnColorDefault 43 | } else { 44 | btnLeftMenu.hovered ? btnColorMouseOver : btnColorDefault 45 | } 46 | } 47 | 48 | 49 | background: Rectangle{ 50 | id: bgBtn 51 | color: internal.dynamicColor 52 | Rectangle{ 53 | anchors{ 54 | top: parent.top 55 | left: parent.left 56 | bottom: parent.bottom 57 | } 58 | color: activeMenuColor 59 | width: 5 60 | visible: isActiveMenu 61 | } 62 | 63 | Rectangle{ 64 | anchors{ 65 | top: parent.top 66 | right: parent.right 67 | bottom: parent.bottom 68 | } 69 | color: activeMenuColorRight 70 | width: 5 71 | visible: isActiveMenu 72 | } 73 | 74 | } 75 | 76 | contentItem: Item{ 77 | anchors.fill: parent 78 | id: content 79 | Image { 80 | id: iconBtn 81 | source: btnIconSource 82 | anchors.leftMargin: 15 83 | anchors.verticalCenter: parent.verticalCenter 84 | anchors.left: parent.left 85 | sourceSize.width: iconWidth 86 | sourceSize.height: iconHeight 87 | width: iconWidth 88 | height: iconHeight 89 | fillMode: Image.PreserveAspectFit 90 | visible: false 91 | antialiasing: true 92 | } 93 | 94 | ColorOverlay{ 95 | anchors.fill: iconBtn 96 | source: iconBtn 97 | color: if(isActiveMenu){activeMenuColorRight } else {"#909090"} 98 | anchors.verticalCenter: parent.verticalCenter 99 | antialiasing: true 100 | width: iconWidth 101 | height: iconHeight 102 | } 103 | 104 | Text{ 105 | color: "#ffffff" 106 | text: btnLeftMenu.text 107 | font: btnLeftMenu.font 108 | anchors.verticalCenter: parent.verticalCenter 109 | anchors.left: parent.left 110 | anchors.leftMargin: 75 111 | } 112 | } 113 | } 114 | /*##^## 115 | Designer { 116 | D{i:0;autoSize:true;height:60;width:250} 117 | } 118 | ##^##*/ 119 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/engine.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/settings_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 62 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/seat_belt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 94 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/icon_app_top.svg: -------------------------------------------------------------------------------- 1 | 2 | 75 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CustomSlider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | 3 | Item { 4 | id:slider 5 | height: heightSlider 6 | 7 | signal released(int value) 8 | signal pressed() 9 | 10 | property real value: 1 11 | onValueChanged: updatePos(); 12 | property real minimum: 1 13 | property real maximum: 1 14 | property real step: 1 15 | property int xMax: width - handle.width 16 | onXMaxChanged: updatePos(); 17 | onMinimumChanged: updatePos(); 18 | 19 | property color backgroundEmpty: "lightgrey"; 20 | property color backgroundFull: "#39F724"; 21 | property real backgroundopacity: 1; 22 | property real backgroundopacityFull: 1; 23 | property color pressCircle: "#39F724" 24 | property color handleGrad1: "lightgray" 25 | property color handleGrad2: "gray" 26 | property real heightSlider: 10 27 | property real fullCircle: 30 28 | property real circleWidth: 70 29 | property real circleHeight: 70 30 | 31 | function updatePos() 32 | { 33 | if (maximum > minimum) 34 | { 35 | var pos = (value - minimum) * slider.xMax / (maximum - minimum); 36 | pos = Math.min(pos, width - handle.width / 2); 37 | pos = Math.max(pos, 0); 38 | handle.x = pos; 39 | } else 40 | { 41 | handle.x = 0; 42 | } 43 | } 44 | 45 | 46 | Rectangle 47 | { 48 | id:background 49 | x: 15 50 | height: heightSlider 51 | width: slider.width - 30 52 | border.color: "white"; border.width: 0; radius: heightSlider *2 53 | color: backgroundEmpty 54 | opacity: backgroundopacity 55 | } 56 | 57 | Rectangle 58 | { 59 | id:sliderFilled 60 | width: handle.x + (handle.width / 2) 61 | height: heightSlider 62 | border.color: "white"; border.width: 0; radius: heightSlider * 2 63 | color: backgroundFull 64 | opacity: backgroundopacityFull 65 | } 66 | 67 | 68 | Rectangle 69 | { 70 | id: handle; smooth: true 71 | width: fullCircle; height: fullCircle; radius: fullCircle/2 72 | anchors.verticalCenter: parent.verticalCenter 73 | gradient: Gradient 74 | { 75 | GradientStop { position: 0.0; color: handleGrad1 } 76 | GradientStop { position: 1.0; color: handleGrad1 } 77 | } 78 | 79 | Rectangle 80 | { 81 | id:circle; smooth: true 82 | visible:false 83 | anchors.verticalCenter: parent.verticalCenter 84 | anchors.horizontalCenter: parent.horizontalCenter 85 | width:circleWidth 86 | height: circleHeight; radius: circleWidth/2 87 | color:"transparent" 88 | border.width: 4 89 | border.color: pressCircle 90 | } 91 | 92 | MouseArea 93 | { 94 | id: mouse 95 | anchors.verticalCenter: parent.verticalCenter 96 | anchors.horizontalCenter: parent.horizontalCenter 97 | width:70 98 | height: 70 99 | drag.target: parent 100 | drag.axis: Drag.XAxis; drag.minimumX: 0; drag.maximumX: slider.xMax 101 | 102 | onPositionChanged: 103 | { 104 | var stepPixel = ((slider.width - 30) * slider.step) / (maximum - minimum); 105 | var numSteps = Math.round(handle.x / stepPixel); 106 | handle.x = numSteps * stepPixel; 107 | value = Math.round(numSteps * slider.step) + minimum; 108 | } 109 | 110 | onPressed: 111 | { 112 | circle.visible = true; 113 | slider.pressed(); 114 | } 115 | 116 | onReleased: 117 | { 118 | circle.visible = false; 119 | var stepPixel = ((slider.width - 30) * slider.step) / (maximum - minimum); 120 | var numSteps = Math.round(handle.x / stepPixel); 121 | handle.x = numSteps * stepPixel; 122 | value = Math.round(numSteps * slider.step) + minimum; 123 | slider.released(value); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/__Slider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | 3 | Item { 4 | id:slider 5 | height: heightSlider 6 | 7 | signal released(int value) 8 | signal pressed() 9 | 10 | property real value: 1 11 | onValueChanged: updatePos(); 12 | property real minimum: 1 13 | property real maximum: 1 14 | property real step: 1 15 | property int xMax: width - handle.width 16 | onXMaxChanged: updatePos(); 17 | onMinimumChanged: updatePos(); 18 | 19 | property color backgroundEmpty: "lightgrey"; 20 | property color backgroundFull: "#39F724"; 21 | property real backgroundopacity: 1; 22 | property real backgroundopacityFull: 1; 23 | property color pressCircle: "#39F724" 24 | property color handleGrad1: "lightgray" 25 | property color handleGrad2: "gray" 26 | property real heightSlider: 10 27 | property real fullCircle: 30 28 | property real circleWidth: 70 29 | property real circleHeight: 70 30 | 31 | function updatePos() 32 | { 33 | if (maximum > minimum) 34 | { 35 | var pos = (value - minimum) * slider.xMax / (maximum - minimum); 36 | pos = Math.min(pos, width - handle.width / 2); 37 | pos = Math.max(pos, 0); 38 | handle.x = pos; 39 | } else 40 | { 41 | handle.x = 0; 42 | } 43 | } 44 | 45 | 46 | Rectangle 47 | { 48 | id:background 49 | x: 15 50 | height: heightSlider 51 | width: slider.width - 30 52 | border.color: "white"; border.width: 0; radius: heightSlider *2 53 | color: backgroundEmpty 54 | opacity: backgroundopacity 55 | } 56 | 57 | Rectangle 58 | { 59 | id:sliderFilled 60 | width: handle.x + (handle.width / 2) 61 | height: heightSlider 62 | border.color: "white"; border.width: 0; radius: heightSlider * 2 63 | color: backgroundFull 64 | opacity: backgroundopacityFull 65 | } 66 | 67 | 68 | Rectangle 69 | { 70 | id: handle; 71 | smooth: true 72 | width: fullCircle; 73 | height: fullCircle; 74 | radius: fullCircle/2 75 | anchors.verticalCenter: parent.verticalCenter 76 | gradient: Gradient 77 | { 78 | GradientStop { position: 0.0; color: handleGrad1 } 79 | GradientStop { position: 1.0; color: handleGrad1 } 80 | } 81 | 82 | Rectangle 83 | { 84 | id:cerchio; 85 | smooth: true 86 | visible:false 87 | anchors.verticalCenter: parent.verticalCenter 88 | anchors.horizontalCenter: parent.horizontalCenter 89 | width:circleWidth 90 | height: circleHeight; radius: circleWidth/2 91 | color:"transparent" 92 | border.width: 4 93 | border.color: pressCircle 94 | } 95 | 96 | MouseArea 97 | { 98 | id: mouse 99 | anchors.verticalCenter: parent.verticalCenter 100 | anchors.horizontalCenter: parent.horizontalCenter 101 | width:70 102 | height: 70 103 | drag.target: parent 104 | drag.axis: Drag.XAxis; drag.minimumX: 0; drag.maximumX: slider.xMax 105 | 106 | onPositionChanged: 107 | { 108 | var stepPixel = ((slider.width - 30) * slider.step) / (maximum - minimum); 109 | var numSteps = Math.round(handle.x / stepPixel); 110 | handle.x = numSteps * stepPixel; 111 | value = Math.round(numSteps * slider.step) + minimum; 112 | } 113 | 114 | onPressed: 115 | { 116 | cerchio.visible = true; 117 | slider.pressed(); 118 | } 119 | 120 | onReleased: 121 | { 122 | cerchio.visible = false; 123 | var stepPixel = ((slider.width - 30) * slider.step) / (maximum - minimum); 124 | var numSteps = Math.round(handle.x / stepPixel); 125 | handle.x = numSteps * stepPixel; 126 | value = Math.round(numSteps * slider.step) + minimum; 127 | slider.released(value); 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/CustomSwitch.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.0 3 | 4 | Item 5 | { 6 | id: toggleswitch 7 | width: background.width; 8 | height: background.height 9 | 10 | signal released(bool value) 11 | signal switched(bool on) 12 | 13 | property bool on: false 14 | property bool toggleEnabled : true 15 | property color colorbg: "#39F724" 16 | 17 | property int backgroundWidth: 70 18 | property int backgroundHeight: 30 19 | 20 | function toggle() 21 | { 22 | if (toggleswitch.state == "on") 23 | toggleswitch.state = "off"; 24 | else 25 | toggleswitch.state = "on"; 26 | switched(toggleswitch.on); 27 | } 28 | 29 | function setStatus(value) 30 | { 31 | if (value === "on") 32 | toggleswitch.state = "on"; 33 | else 34 | toggleswitch.state = "off"; 35 | } 36 | 37 | function releaseSwitch() 38 | { 39 | if (knob.x == 1) 40 | { 41 | if (toggleswitch.state == "off") 42 | { 43 | toggleswitch.on = false; 44 | return; 45 | } 46 | } 47 | if (knob.x == 40) 48 | { 49 | if (toggleswitch.state == "on") 50 | { 51 | toggleswitch.on = true; 52 | return; 53 | } 54 | } 55 | toggle(); 56 | } 57 | 58 | Rectangle 59 | { 60 | id: background 61 | width: backgroundWidth 62 | height: backgroundHeight 63 | radius: height 64 | color: "#313E53" 65 | y : 5 66 | 67 | MouseArea 68 | { 69 | anchors.fill: parent; 70 | onClicked: toggle(); 71 | enabled:toggleEnabled 72 | } 73 | Text { 74 | id: textox 75 | text: "ON" 76 | font.pointSize: 12 77 | font.bold: true 78 | anchors.left: parent.left 79 | anchors.leftMargin: 10 80 | anchors.verticalCenter: parent.verticalCenter 81 | } 82 | 83 | Text { 84 | id: textoy 85 | text: "OFF" 86 | color: "#e0e0e0" 87 | font.pointSize: 12 88 | font.bold: true 89 | anchors.right: parent.right 90 | anchors.rightMargin: 10 91 | anchors.verticalCenter: parent.verticalCenter 92 | } 93 | 94 | } 95 | 96 | Rectangle 97 | { 98 | id: knob 99 | width: backgroundHeight+10; 100 | height: backgroundHeight+10 101 | radius: width 102 | gradient: Gradient 103 | { 104 | GradientStop { position: 0.0; color: "#a0a0a0" } 105 | GradientStop { position: 1.0; color: "#e0e0e0" } 106 | } 107 | 108 | MouseArea 109 | { 110 | anchors.fill: parent 111 | enabled:toggleEnabled 112 | drag.target: knob; 113 | drag.axis: Drag.XAxis; 114 | drag.minimumX: 1; 115 | drag.maximumX: backgroundWidth-backgroundHeight //40 116 | onClicked: 117 | { 118 | toggle(); 119 | } 120 | onReleased: 121 | { 122 | releaseSwitch(); 123 | toggleswitch.released(on); 124 | } 125 | } 126 | } 127 | 128 | Rectangle 129 | { 130 | id: backgroundDisabled 131 | width: 70; 132 | height: 30 133 | radius: 30 134 | color: "#313E53" 135 | opacity: 0.8 136 | visible: !toggleEnabled 137 | 138 | } 139 | 140 | states: 141 | [ 142 | State 143 | { 144 | name: "on" 145 | PropertyChanges { target: knob; x: backgroundWidth-backgroundHeight-10 } 146 | PropertyChanges { target: toggleswitch; on: true } 147 | PropertyChanges { target: background; color: toggleswitch.colorbg } 148 | 149 | }, 150 | State 151 | { 152 | name: "off" 153 | PropertyChanges { target: knob; x: 1 } 154 | PropertyChanges { target: toggleswitch; on: false } 155 | PropertyChanges { target: background; color: "#313E53" } 156 | } 157 | ] 158 | 159 | transitions: 160 | Transition 161 | { 162 | NumberAnimation { properties: "x"; easing.type: Easing.InOutQuad; duration: 200 } 163 | } 164 | } 165 | 166 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/chartPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Window 2.15 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Controls.Styles 1.4 5 | import QtQuick.Extras 1.4 6 | import QtQuick.Extras.Private 1.0 7 | 8 | 9 | //import QtQuick 2.0 10 | import QtCharts 2.1 11 | import "../controls" 12 | 13 | 14 | Item { 15 | 16 | Text { 17 | id: title 18 | text: qsTr("Analog Measure - Volatile chart") 19 | anchors.top: parent.top 20 | anchors.horizontalCenter: parent.horizontalCenter 21 | anchors.topMargin: 5 22 | font.pointSize :18 23 | color: "#a0a0a0" 24 | } 25 | //########## INI CHART VIEW ############################## 26 | 27 | ChartView{ 28 | id:cv 29 | anchors{ 30 | top:title.bottom 31 | topMargin:10 32 | left:parent.left 33 | right:parent.right 34 | bottom:parent.bottom 35 | bottomMargin:10 36 | leftMargin:10 37 | rightMargin:10 38 | } 39 | antialiasing: true 40 | theme: ChartView.ChartThemeDark 41 | 42 | property int timcnt: 0 43 | property double valueCH1: 0 44 | property double valueCH2: 0 45 | property double valueCH3: 0 46 | property double valueCH4: 0 47 | //property double valueTM1: 0 48 | property double periodGRAPH: 30 // Seconds 49 | property double startTIME: 0 50 | property double intervalTM: 200 // miliseconds 51 | 52 | ValueAxis{ 53 | id:yAxis 54 | min: 0 55 | max: 1000 56 | tickCount: 1 57 | labelFormat: "%d" 58 | } 59 | 60 | LineSeries { 61 | name: "AIN 0" 62 | id:lines1 63 | //axisX: xAxis 64 | axisY: yAxis 65 | width: 2 66 | color: "#1267D4" 67 | axisX: DateTimeAxis { 68 | id: eje 69 | //format: "yyyy MMM" 70 | format:"HH:mm:ss.z" 71 | //format:"mm:ss.z" 72 | } 73 | } 74 | 75 | LineSeries { 76 | name: "AIN 1" 77 | id:lines2 78 | axisX: eje 79 | axisY: yAxis 80 | width: 2 81 | color: "#ffa500" 82 | } 83 | 84 | LineSeries { 85 | name: "AIN 2" 86 | id:lines3 87 | axisX: eje 88 | axisY: yAxis 89 | width: 2 90 | color: "#a5ff00" 91 | } 92 | 93 | LineSeries { 94 | name: "AIN 3" 95 | id:lines4 96 | axisX: eje 97 | axisY: yAxis 98 | width: 2 99 | color: "#ff0000" 100 | } 101 | 102 | /// 103 | Timer{ 104 | id:tm 105 | interval: cv.intervalTM 106 | repeat: true 107 | running: true 108 | onTriggered: { 109 | cv.timcnt = cv.timcnt + 1 110 | //cv.valueTM1 = backend.get_tiempo()*1000 111 | cv.valueCH1 = backend.get_adc1() 112 | cv.valueCH2 = backend.get_adc2() 113 | cv.valueCH3 = backend.get_adc3() 114 | cv.valueCH4 = backend.get_adc4() 115 | 116 | if (lines1.count>cv.periodGRAPH*1000/cv.intervalTM){ 117 | lines1.remove(0) 118 | lines2.remove(0) 119 | lines3.remove(0) 120 | lines4.remove(0) 121 | } 122 | 123 | lines1.append(cv.startTIME+cv.timcnt*cv.intervalTM ,cv.valueCH1) 124 | lines2.append(cv.startTIME+cv.timcnt*cv.intervalTM ,cv.valueCH2) 125 | lines3.append(cv.startTIME+cv.timcnt*cv.intervalTM ,cv.valueCH3) 126 | lines4.append(cv.startTIME+cv.timcnt*cv.intervalTM ,cv.valueCH4) 127 | 128 | //lines1.append(cv.valueTM1+cv.timcnt*500 ,cv.valueCH1) 129 | //lines2.append(cv.valueTM1+cv.timcnt*500 ,cv.valueCH2) 130 | //lines3.append(cv.valueTM1+cv.timcnt*500 ,cv.valueCH3) 131 | //lines4.append(cv.valueTM1+cv.timcnt*500 ,cv.valueCH4) 132 | 133 | //lines1.axisX.min = cv.timcnt < cv.periodGRAPH ? new Date(cv.startTIME) : new Date(cv.startTIME - cv.periodGRAPH*1000 + cv.timcnt*1000) 134 | //lines1.axisX.max = cv.timcnt < cv.periodGRAPH ? new Date(cv.startTIME + cv.periodGRAPH*1000) : new Date(cv.startTIME + cv.timcnt*1000) 135 | 136 | //lines1.axisX.min = new Date(cv.startTIME-cv.periodGRAPH*1000 + cv.timcnt*500) 137 | //lines1.axisX.max = new Date(cv.startTIME + cv.timcnt*500) 138 | 139 | lines1.axisX.min = new Date(cv.startTIME-cv.periodGRAPH*1000 + cv.timcnt*cv.intervalTM) 140 | lines1.axisX.max = new Date(cv.startTIME + cv.timcnt*cv.intervalTM) 141 | } 142 | } 143 | 144 | } 145 | Component.onCompleted: { 146 | cv.startTIME = backend.get_tiempo()*1000 147 | } 148 | 149 | 150 | //########## END CHART VIEW ############################## 151 | 152 | Connections{ 153 | target: backend 154 | 155 | } 156 | } 157 | 158 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/controls/_ItemParam.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | 3 | Item 4 | { 5 | width: 200 6 | height: width 7 | 8 | property string title: " " 9 | property string unit: " " 10 | property real paramValue: 0 11 | property real minValue: 0 12 | property real maxValue: 100 13 | property real regMinValue: 1 14 | property real regMaxValue: 50 15 | 16 | FontLoader 17 | { 18 | id: fontHelveticaSemibold 19 | source:"images/helvetica.ttf" 20 | } 21 | 22 | Rectangle 23 | { 24 | anchors.centerIn: parent 25 | width: parent.width 26 | height: width 27 | radius: width * 0.5 28 | color: "black" 29 | opacity: 0.4 30 | } 31 | 32 | Rectangle 33 | { 34 | id:ctrlVolume 35 | color: "transparent" 36 | width: parent.width 37 | height: width 38 | radius: width * 0.5 39 | anchors.centerIn: parent 40 | 41 | Text // Titolo del parametro 42 | { 43 | id:paramName 44 | text: title 45 | color: "#CCFFFF" 46 | anchors.horizontalCenter: parent.horizontalCenter 47 | anchors.bottom: parent.bottom 48 | anchors.bottomMargin: 25 49 | font.pointSize: 15 50 | font.family: fontHelvetica.name 51 | } 52 | 53 | 54 | 55 | Text // Valore del parametro 56 | { 57 | id: textValue 58 | text: paramValue 59 | color: "white" 60 | anchors.horizontalCenter: parent.horizontalCenter 61 | anchors.verticalCenter: parent.verticalCenter 62 | font.pointSize: 30 63 | font.family: fontHelveticaSemibold.name 64 | } 65 | 66 | Text // Unità di misura del parametro 67 | { 68 | text: unit 69 | color: "white" 70 | anchors.horizontalCenter: parent.horizontalCenter 71 | anchors.bottomMargin: 18 72 | anchors.bottom: parent.bottom 73 | font.pointSize: 16 74 | font.family: fontHelveticaSemibold.name 75 | } 76 | 77 | Canvas 78 | { 79 | id: canvas 80 | anchors.centerIn: parent 81 | width: parent.width - 10 82 | height: width 83 | antialiasing: true 84 | smooth: true 85 | visible: true 86 | 87 | signal bar_event() 88 | property color primaryColor: "lightgrey"//"#778899" // Sfondo 89 | property color secondaryColor: "red" //"#FFA500"//"#00ff00" // Riempimento 90 | 91 | property real centerWidth: (width / 2) 92 | property real centerHeight: (height / 2) 93 | property real radius: (width - 15) / 2 94 | 95 | property real minimumValue: minValue 96 | property real maximumValue: maxValue 97 | property real currentValueR: paramValue 98 | property real angle: (currentValueR - minimumValue) / (maximumValue - minimumValue) * (endAngle - startAngle) 99 | property real startAngle: Math.PI - 1 100 | property real endAngle: Math.PI * 2 + 1 101 | property string text: "Più" 102 | property string text2: "Meno" 103 | 104 | signal clicked() 105 | onPrimaryColorChanged: requestPaint() 106 | onSecondaryColorChanged: requestPaint() 107 | onMinimumValueChanged: requestPaint() 108 | onMaximumValueChanged: requestPaint() 109 | onCurrentValueRChanged: requestPaint() 110 | 111 | onPaint: 112 | { 113 | var ctx = getContext("2d"); 114 | ctx.save(); 115 | /* 116 | ctx.clearRect(0, 0, canvas.width, canvas.height); 117 | ctx.beginPath(); 118 | ctx.lineWidth = 10; 119 | ctx.arc(currentValueR); 120 | ctx.fill(canvas.text); 121 | */ 122 | ctx.beginPath(); 123 | ctx.lineWidth = 12; 124 | ctx.lineCap = "round" 125 | ctx.strokeStyle = primaryColor; 126 | ctx.arc(canvas.centerWidth, 127 | canvas.centerHeight, 128 | canvas.radius, 129 | startAngle, 130 | endAngle); 131 | ctx.stroke(); 132 | 133 | ctx.beginPath(); 134 | ctx.lineWidth = 12; 135 | ctx.lineCap = "round" 136 | ctx.strokeStyle = canvas.secondaryColor; 137 | 138 | ctx.arc(canvas.centerWidth, 139 | canvas.centerHeight, 140 | canvas.radius, 141 | canvas.startAngle, 142 | canvas.startAngle + canvas.angle); 143 | ctx.stroke(); 144 | ctx.restore(); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Dashboard_qml/arduino_code/arduino_code.ino: -------------------------------------------------------------------------------- 1 | // ################################################################################ 2 | // Programa de ejemplo para tablero de control usando PYQT QT como interfaz grafica. 3 | // Cualquier aporte, mejora, a mi correo JAHIRG@YAHOO.COM 4 | // No soy experto en programacion, quiero aprender. 5 | // Este codigo es desean hace proyectos usando interfaz grafica en pc 6 | // 7 | // Example program for a control panel using PYQT QT as a graphical interface. 8 | // Any contribution, improvement, to my mail JAHIRG@YAHOO.COM 9 | // I am not an expert in programming, I want to learn. 10 | // This code is to make projects using graphical interface on PC. 11 | // ############################################################################### 12 | 13 | //###################################################################### 14 | //# LISTA DE REGISTROS USADOS EN EL PROGRAMA 15 | //# LIST OF REGISTERS USED IN THE PROGRAM 16 | //###################################################################### 17 | 18 | // #### Registros de prueba son 16 datos de 16 bits.(0-7 ADC, 8-15 DIN) 19 | // #### Test registers are 16 data of 16 bits (0-7 ADC, 8-15 DIN). 20 | int au16data[16] = { 21 | 300, 102, 1003, 104, 10000, 20000, 30000, 32000, 0, 0, 0, 0, 0, 0, 1, 1 }; 22 | const size_t dataLength = 16; 23 | int Period1, Period2; 24 | unsigned long Time1, Time2; 25 | 26 | //###################################################################### 27 | //# DEFINICION DE PINES: 28 | //# NO USAR INSTRUCCIONES PULL UP, CAUSAN FALLAS EN COMUNICACIONES 29 | // 30 | //# PIN CONFIGURATION: 31 | //# PLEASE DONT USE PULLUP INSTRUCTIONS CAUSE FAULT IN COMMUNICTIONS 32 | //###################################################################### 33 | 34 | void setup() { 35 | 36 | // #### ajustes en comunicacion. 37 | Period1 = 200; 38 | Period2 = 2; 39 | 40 | // #### slider para PMW 41 | pinMode(4,OUTPUT); 42 | pinMode(5,OUTPUT); 43 | pinMode(6,OUTPUT); 44 | pinMode(7,OUTPUT); 45 | pinMode(8,OUTPUT); 46 | pinMode(9,OUTPUT); 47 | pinMode(10,OUTPUT); 48 | pinMode(11,OUTPUT); 49 | 50 | // ### Senales de pulsadores 51 | pinMode(62,INPUT); 52 | pinMode(63,INPUT); 53 | pinMode(64,INPUT); 54 | pinMode(65,INPUT); 55 | pinMode(66,INPUT); 56 | pinMode(67,INPUT); 57 | pinMode(68,INPUT); 58 | pinMode(69,INPUT); 59 | 60 | // ### Senales para indicadores 61 | pinMode(22,OUTPUT); 62 | pinMode(23,OUTPUT); 63 | pinMode(24,OUTPUT); 64 | pinMode(25,OUTPUT); 65 | pinMode(26,OUTPUT); 66 | pinMode(27,OUTPUT); 67 | pinMode(28,OUTPUT); 68 | pinMode(29,OUTPUT); 69 | 70 | Serial.begin( 9600 ); // baud-rate at 9600 71 | } 72 | 73 | //################################################################## 74 | //# ENVIO DE DATOS AL PC 75 | //# SENDING DATA TO THE PC 76 | //################################################################## 77 | void sendBytes(uint16_t value) 78 | { 79 | Serial.write(highByte(value)); 80 | Serial.write(lowByte(value)); 81 | } 82 | //################################################################## 83 | //# ACTIVACION LEDS H/L 84 | //################################################################## 85 | void vProcessaUart(String s){ 86 | 87 | if(s == "22H") 88 | digitalWrite(22,HIGH); 89 | if(s == "22L") 90 | digitalWrite(22,LOW); 91 | 92 | if(s == "23H") 93 | digitalWrite(23,HIGH); 94 | if(s == "23L") 95 | digitalWrite(23,LOW); 96 | 97 | if(s == "24H") 98 | digitalWrite(24,HIGH); 99 | if(s == "24L") 100 | digitalWrite(24,LOW); 101 | 102 | if(s == "25H") 103 | digitalWrite(25,HIGH); 104 | if(s == "25L") 105 | digitalWrite(25,LOW); 106 | 107 | if(s == "26H") 108 | digitalWrite(26,HIGH); 109 | if(s == "26L") 110 | digitalWrite(26,LOW); 111 | 112 | if(s == "27H") 113 | digitalWrite(27,HIGH); 114 | if(s == "27L") 115 | digitalWrite(27,LOW); 116 | 117 | if(s == "28H") 118 | digitalWrite(28,HIGH); 119 | if(s == "28L") 120 | digitalWrite(28,LOW); 121 | 122 | if(s == "29H") 123 | digitalWrite(29,HIGH); 124 | if(s == "29L") 125 | digitalWrite(29,LOW); 126 | 127 | //##################################################################### 128 | //# SECCION PWM 129 | //##################################################################### 130 | String pwm =s; 131 | int datapwm=0; 132 | pwm.remove(0, 3); 133 | datapwm=pwm.toInt(); 134 | s.remove(3); 135 | 136 | if(s == "P04") 137 | analogWrite(4, datapwm); 138 | if(s == "P05") 139 | analogWrite(5, datapwm); 140 | if(s == "P06") 141 | analogWrite(6, datapwm); 142 | if(s == "P07") 143 | analogWrite(7, datapwm); 144 | if(s == "P08") 145 | analogWrite(8, datapwm); 146 | if(s == "P09") 147 | analogWrite(9, datapwm); 148 | if(s == "P10") 149 | analogWrite(10, datapwm); 150 | if(s == "P11") 151 | analogWrite(11, datapwm); 152 | } 153 | 154 | //##################################################################### 155 | //# BUCLE PRINCIPAL 156 | //# MAIN LOOP 157 | //##################################################################### 158 | void loop() { 159 | // #### Registros 0 al 7 son entradas analogos 160 | // #### Registers 0 to 7 are analog inputs 161 | au16data[0]=analogRead(A0); 162 | au16data[1]=analogRead(A1); 163 | au16data[2]=analogRead(A2); 164 | au16data[3]=analogRead(A3); 165 | au16data[4]=analogRead(A4); 166 | au16data[5]=analogRead(A5); 167 | au16data[6]=analogRead(A6); 168 | au16data[7]=analogRead(A7); 169 | 170 | // #### Registros 8 al 15 son entradas digitales 171 | // #### Registers 8 to 15 are digital inputs 172 | if(digitalRead(62)) 173 | au16data[8]=621; 174 | else 175 | au16data[8]=620; 176 | 177 | if(digitalRead(63)) 178 | au16data[9]=631; 179 | else 180 | au16data[9]=630; 181 | 182 | if(digitalRead(64)) 183 | au16data[10]=641; 184 | else 185 | au16data[10]=640; 186 | 187 | if(digitalRead(65)) 188 | au16data[11]=651; 189 | else 190 | au16data[11]=650; 191 | 192 | if(digitalRead(66)) 193 | au16data[12]=661; 194 | else 195 | au16data[12]=660; 196 | 197 | if(digitalRead(67)) 198 | au16data[13]=671; 199 | else 200 | au16data[13]=670; 201 | 202 | if(digitalRead(68)) 203 | au16data[14]=681; 204 | else 205 | au16data[14]=680; 206 | 207 | if(digitalRead(69)) 208 | au16data[15]=691; 209 | else 210 | au16data[15]=690; 211 | 212 | 213 | //#### Envio de datos al PC 214 | //#### Sending data to the PC 215 | if (millis()-Time1 >= Period1) { 216 | for(int n = 0; n < 16; n++){ 217 | sendBytes(au16data[n]); 218 | } 219 | Time1 = millis(); 220 | } 221 | 222 | //#### Captura de datos del PC 223 | //#### PC data capture 224 | String sz = ""; 225 | char ch; 226 | int nCmpt = 0; 227 | while (Serial.available() > 0) { 228 | if (millis()-Time2 >= Period2) { 229 | sz += (char)Serial.read(); 230 | nCmpt++; 231 | Time2 = millis(); 232 | } 233 | } 234 | if(nCmpt) 235 | vProcessaUart(sz); 236 | 237 | } 238 | -------------------------------------------------------------------------------- /Dashboard_qml/images/svg_images/051-cpu.svg: -------------------------------------------------------------------------------- 1 | 2 | 69 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/bonusPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtCharts 2.1 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Layouts 1.0 5 | import "../controls" 6 | 7 | Item { 8 | 9 | Rectangle { 10 | id: rectangle 11 | color: "#1c313c" 12 | anchors.fill: parent 13 | 14 | ///###### INI RECTANGLE PANEL ################################## 15 | Rectangle { 16 | id: panel 17 | anchors.top: parent.top 18 | anchors.topMargin: 10 19 | anchors.bottom: parent.bottom 20 | anchors.left: parent.left 21 | anchors.leftMargin: 10 22 | width: 160 23 | color: "#1c313c" 24 | 25 | ColumnLayout { 26 | anchors.left: parent.left 27 | anchors.leftMargin: 20 28 | spacing: 8 29 | 30 | Text { 31 | text: "Scope" 32 | font.pointSize: 18 33 | font.bold: true 34 | color: "#ff0000" 35 | } 36 | 37 | MultiButton { 38 | id: btnSerieType 39 | text: "Graph: " 40 | items: ["line", "scatter"] 41 | onSelectionChanged: { 42 | //console.debug("test serie "+ btnSerieType.items[currentSelection]) 43 | cv2.changeSeriesType(btnSerieType.items[currentSelection]) 44 | } 45 | } 46 | 47 | MultiButton { 48 | id: btnRefreshType 49 | text: "Refresh seg: " 50 | items: ["1", "2", "3"] 51 | onSelectionChanged: { 52 | //console.debug("test refresh "+ btnRefreshType.items[currentSelection] ) 53 | cv2.changeRefreshRate(btnRefreshType.items[currentSelection]) 54 | } 55 | } 56 | 57 | MultiButton { 58 | id: btnAntialias 59 | text: "Antialias: " 60 | items: ["OFF", "ON"] 61 | onSelectionChanged : { 62 | //console.debug("test antialias " + btnAntialias.items[currentSelection]); 63 | cv2.antialiaschange(btnAntialias.items[currentSelection]) 64 | } 65 | } 66 | Rectangle { 67 | color: "#00000000" 68 | width: 150 69 | height: 150 70 | Text { 71 | color: "#e0e0e0" 72 | font.pointSize: 8 73 | text: "The data plotted here are randomly generated. This is an example of how data is imported into a series. The source of the data can be from a CSV or a database." 74 | width: 150 75 | height: 100 76 | wrapMode: Text.WordWrap 77 | } 78 | } 79 | } 80 | } 81 | ///###### END RECTANGLE PANEL ################################## 82 | 83 | ///###### INIT SCOPE VIEW ###################################### 84 | Rectangle { 85 | id: view 86 | anchors.top: parent.top 87 | anchors.bottom: parent.bottom 88 | anchors.left: panel.right 89 | anchors.leftMargin: 10 90 | anchors.right: parent.right 91 | anchors.rightMargin: 10 92 | color: "#2C313C" 93 | 94 | ChartView{ 95 | id:cv2 96 | anchors.top: parent.top 97 | anchors.bottom: parent.bottom 98 | anchors.left: parent.left 99 | anchors.right: parent.right 100 | antialiasing: true 101 | //theme: ChartView.ChartThemeDark 102 | 103 | title: "Custom QtChart demo from data simulated" 104 | titleColor: "#00ff00" 105 | titleFont.pointSize:12 106 | titleFont.bold:true 107 | legend.visible: true 108 | legend.alignment: Qt.AlignBottom 109 | legend.labelColor : "#d0d0d0" 110 | legend.font.pixelSize:12 111 | 112 | backgroundColor : "#00000000" 113 | 114 | 115 | ValueAxis { 116 | id: axisY1 117 | min: -50 118 | max: 50 119 | titleText:"Scale for IR Signal 1 and IR Signal 2" 120 | color:"#00ff00" 121 | labelsColor: "#D68B00" 122 | } 123 | ValueAxis { 124 | id: axisY2 125 | min: -150 126 | max: 150 127 | titleText:"Scale for IR Signal 3 and IR Signal 4" 128 | color:"#ffa500" 129 | labelsColor: "#00AD00" 130 | } 131 | 132 | ValueAxis { 133 | id: axisX 134 | min: 0 135 | max: 128 136 | titleText:"Number of samples" 137 | color:"#0080ff" 138 | labelsColor: "#00F4FF" 139 | } 140 | 141 | LineSeries { 142 | name: "IR signal 1" 143 | id:lines1 144 | axisX: axisX 145 | axisY: axisY1 146 | width: 1 147 | color: "#00a5ff" 148 | } 149 | 150 | LineSeries { 151 | name: "IR signal 2" 152 | id:lines2 153 | axisX: axisX 154 | axisY: axisY1 155 | width: 1 156 | color: "#ffa500" 157 | } 158 | 159 | LineSeries { 160 | name: "IR signal 3" 161 | id:lines3 162 | axisX: axisX 163 | axisYRight: axisY2 164 | width: 1 165 | color: "#a5ff00" 166 | } 167 | 168 | LineSeries { 169 | name: "IR signal 4" 170 | id:lines4 171 | axisX: axisX 172 | axisYRight: axisY2 173 | width: 1 174 | color: "#ff0000" 175 | } 176 | 177 | Timer { 178 | id: refreshTimer 179 | interval: 750 180 | running: true 181 | repeat: true 182 | onTriggered: { 183 | backend.update0(cv2.series(0)); 184 | backend.update1(cv2.series(1)); 185 | backend.update2(cv2.series(2)); 186 | backend.update3(cv2.series(3)); 187 | } 188 | } 189 | 190 | function changeSeriesType(type) { 191 | cv2.removeAllSeries(); 192 | // Create new series of the correct type. Axis x is the same for all series, 193 | // but the series have their own y-axes to make it possible to control the y-offset 194 | // of the "signal sources". 195 | if (type == "line") { 196 | var series1 = cv2.createSeries(ChartView.SeriesTypeLine, "IR signal 1",axisX, axisY1); 197 | series1.width = 2; 198 | series1.color = "#ffa500"; 199 | 200 | var series2 = cv2.createSeries(ChartView.SeriesTypeLine, "IR signal 2", axisX, axisY1); 201 | series2.width = 2; 202 | series2.color = "#a5ff00"; 203 | 204 | var series3 = cv2.createSeries(ChartView.SeriesTypeLine, "IR signal 3", axisX, axisY1); 205 | series3.width = 2; 206 | series3.color = "#00a5ff"; 207 | 208 | var series4 = cv2.createSeries(ChartView.SeriesTypeLine, "IR signal 4", axisX, axisY1); 209 | series4.width = 2; 210 | series4.color = "#ff0000"; 211 | } 212 | else { 213 | var series1 = cv2.createSeries(ChartView.SeriesTypeScatter, "IR signal 1",axisX, axisY1); 214 | series1.markerSize = 3; 215 | series1.color = "#ffa500"; 216 | series1.borderColor = "transparent"; 217 | 218 | var series2 = cv2.createSeries(ChartView.SeriesTypeScatter, "IR signal 2", axisX, axisY1); 219 | series2.markerSize = 3; 220 | series2.color = "#a5ff00"; 221 | series2.borderColor = "transparent"; 222 | 223 | var series3 = cv2.createSeries(ChartView.SeriesTypeScatter, "IR signal 3",axisX, axisY1); 224 | series3.markerSize = 3; 225 | series3.color = "#00a5ff"; 226 | series3.borderColor = "transparent"; 227 | 228 | var series4 = cv2.createSeries(ChartView.SeriesTypeScatter, "IR signal 4", axisX, axisY1); 229 | series4.markerSize = 3; 230 | series4.color = "#ff0000"; 231 | series4.borderColor = "transparent"; 232 | } 233 | } 234 | 235 | function changeRefreshRate(rate) { 236 | refreshTimer.interval = Number(rate) * 1000; 237 | } 238 | 239 | function antialiaschange(status) { 240 | if(status=="ON") { 241 | cv2.antialiasing = true 242 | } 243 | else { 244 | cv2.antialiasing = false 245 | } 246 | } 247 | } 248 | } 249 | ///###### END SCOPE VIEW #################### 250 | } 251 | } 252 | 253 | 254 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/settingsPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtQuick.Controls 2.15 3 | import "../controls" 4 | import QtQuick.Layouts 1.0 5 | 6 | Item { 7 | Rectangle { 8 | id: rectangle 9 | color: "#2c313c" 10 | anchors.fill: parent 11 | 12 | Rectangle { 13 | id: rectangleTop 14 | height: 69 15 | color: "#495163" 16 | radius: 10 17 | anchors.left: parent.left 18 | anchors.right: parent.right 19 | anchors.top: parent.top 20 | anchors.rightMargin: 50 21 | anchors.leftMargin: 50 22 | anchors.topMargin: 40 23 | 24 | GridLayout { 25 | anchors.fill: parent 26 | anchors.rightMargin: 10 27 | anchors.leftMargin: 10 28 | rows: 1 29 | columns: 3 30 | 31 | CustomTextField{ 32 | id: textField 33 | placeholderText: "Type your name" 34 | Layout.fillWidth: true 35 | Keys.onEnterPressed: { 36 | backend.welcomeText(textField.text) 37 | } 38 | Keys.onReturnPressed: { 39 | backend.welcomeText(textField.text) 40 | } 41 | } 42 | 43 | CustomButton{ 44 | id: btnChangeName 45 | text: "Change Name" 46 | Layout.maximumWidth: 200 47 | Layout.fillWidth: true 48 | Layout.preferredHeight: 40 49 | Layout.preferredWidth: 250 50 | onClicked: { 51 | backend.welcomeText(textField.text) 52 | } 53 | } 54 | 55 | Switch { 56 | id: switchHome 57 | text: qsTr("Sw") 58 | checked: true 59 | Layout.preferredHeight: 40 60 | Layout.preferredWidth: 68 61 | // Change Show/Hide Frame 62 | onToggled: { 63 | backend.showHideRectangle(switchHome.checked,611) 64 | } 65 | } 66 | } 67 | } 68 | 69 | Rectangle { 70 | id: rectangleVisible 71 | color: "#1d2128" 72 | radius: 10 73 | anchors.left: parent.left 74 | anchors.right: parent.right 75 | anchors.top: rectangleTop.bottom 76 | anchors.bottom: parent.bottom 77 | anchors.bottomMargin: 40 78 | anchors.rightMargin: 50 79 | anchors.leftMargin: 50 80 | anchors.topMargin: 10 81 | 82 | Label { 83 | id: labelTextName 84 | y: 8 85 | height: 25 86 | color: "#5c667d" 87 | text: qsTr("Welcome") 88 | anchors.left: parent.left 89 | anchors.right: parent.right 90 | horizontalAlignment: Text.AlignHCenter 91 | verticalAlignment: Text.AlignVCenter 92 | anchors.leftMargin: 10 93 | anchors.rightMargin: 10 94 | font.pointSize: 14 95 | } 96 | 97 | Label { 98 | id: labelDate 99 | y: 31 100 | height: 25 101 | color: "#55aaff" 102 | text: qsTr("Date") 103 | anchors.left: parent.left 104 | anchors.right: parent.right 105 | horizontalAlignment: Text.AlignHCenter 106 | verticalAlignment: Text.AlignVCenter 107 | anchors.rightMargin: 10 108 | anchors.leftMargin: 10 109 | font.pointSize: 12 110 | } 111 | 112 | ScrollView { 113 | id: scrollView 114 | anchors.left: parent.left 115 | anchors.right: parent.right 116 | anchors.top: labelDate.bottom 117 | anchors.bottom: parent.bottom 118 | clip: true 119 | anchors.rightMargin: 10 120 | anchors.leftMargin: 10 121 | anchors.bottomMargin: 10 122 | anchors.topMargin: 10 123 | 124 | /* 125 | Text { 126 | id: textHome 127 | color: "#a9b2c8" 128 | text:"Bienvenido" 129 | //text: "\n
\nGNU GENERAL PUBLIC LICENSE
\nVersion 3, 29 June 2007
\nCopyright (c) 2020 Wanderson M. Pimenta
\nAttention: this project was created with the Open Souce tools from Qt Company,
\nthis project can be used for studies or personal non-commercial projects.
\nIf you are going to use it for commercial use, you need to purchase a license at "https://www.qt.io".
" 130 | anchors.fill: parent 131 | font.pixelSize: 12 132 | textFormat: Text.RichText 133 | } 134 | */ 135 | Rectangle { 136 | color: "#00000000" 137 | anchors.fill: parent 138 | Text { 139 | anchors.fill: parent 140 | color: "#e0e0e0" 141 | font.pointSize: 12 142 | text : { 143 | "I know many of you are wondering about a tutorial to make this app. 144 | This GUI was developed by Wanderson Pimenta https://www.youtube.com/c/WandersonIsMe. 145 | In his channel is available the tutorial on how to make this app. 146 | 147 | I am not a programmer nor do I work in the IT area, my job has nothing to do with application development. 148 | 149 | I do this as a hobby. During this year 2021 I set out to make modern GUI to interact with arduino. 150 | I came across Wanderson's channel and taking information from different websites like https://www.pythonguis.com , github and several youtube channels. 151 | 152 | Finally I put together this project. 153 | 154 | A special recognition to Zhao Qian on TengZhou City, for his contribution 155 | 156 | My email: jahirg@yahoo.com"} 157 | width: 150 158 | height: 100 159 | wrapMode: Text.WordWrap 160 | } 161 | } 162 | } 163 | } 164 | } 165 | Connections{ 166 | target: backend 167 | 168 | function onSetName(name){ 169 | labelTextName.text = name 170 | } 171 | 172 | function onPrintTime(time){ 173 | labelDate.text = time 174 | } 175 | 176 | function onIsVisible(isVisible){ 177 | rectangleVisible.visible = isVisible 178 | } 179 | } 180 | 181 | } 182 | 183 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/circle_red_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 257 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/circle_orange_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 257 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/circle_yellow_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 257 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/circle_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 90 | -------------------------------------------------------------------------------- /Dashboard_qml/images/png_images/circle_green_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 267 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/inputPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Window 2.15 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Controls.Styles 1.4 5 | import QtQuick.Extras 1.4 6 | import QtQuick.Extras.Private 1.0 7 | import "../controls" 8 | 9 | 10 | import QtGraphicalEffects 1.15 11 | 12 | Item { 13 | //property string bgcolor : "#21be2b" 14 | property int din0status: 0 15 | property int din1status: 0 16 | property int din2status: 0 17 | property int din3status: 0 18 | property int din4status: 0 19 | property int din5status: 0 20 | property int din6status: 0 21 | property int din7status: 0 22 | 23 | //############ INI : Main Rectangle page ########################### 24 | Rectangle { 25 | id: rectangle 26 | color: "#2c313c" 27 | anchors.fill: parent 28 | 29 | //############ INI : Rectangle Container for Inputs ################### 30 | Rectangle 31 | { 32 | id: rectInputs 33 | width: 700 34 | height: 480 35 | anchors.left: parent.left 36 | anchors.leftMargin: 10 37 | anchors.top: parent.top 38 | anchors.topMargin: 10 39 | color: "transparent" 40 | border.color: "gray" 41 | border.width: 2 42 | radius: 10 43 | 44 | //######## Space Title INPUT PAGE ############################# 45 | Text 46 | { 47 | text: qsTr("INPUT PAGE") 48 | anchors.horizontalCenter: parent.horizontalCenter 49 | anchors.top: parent.top 50 | anchors.topMargin: 10 51 | color: "#00a5ff" 52 | font.pointSize: 16 53 | font.bold : true 54 | } 55 | Text { 56 | color: "#ffa500" 57 | font.pointSize: 12 58 | text: "Change SVG image" 59 | anchors.left: parent.left 60 | anchors.leftMargin: 60 61 | anchors.top: parent.top 62 | anchors.topMargin: 65 63 | width: 150 64 | height: 100 65 | 66 | } 67 | 68 | Rectangle { 69 | id : rectdin0 70 | anchors.left: parent.left 71 | anchors.leftMargin: 60 72 | anchors.top: parent.top 73 | anchors.topMargin: 30 74 | width: 200 75 | height: 200 76 | color: "#00000000" 77 | 78 | Text { 79 | text: qsTr("DIN 0") 80 | anchors.verticalCenter : parent.verticalCenter 81 | color: "#00a5ff" 82 | font.pointSize: 16 83 | font.bold : true 84 | } 85 | AnimatedImage { 86 | anchors.verticalCenter : parent.verticalCenter 87 | anchors.left: parent.left 88 | anchors.leftMargin: 80 89 | smooth : true 90 | width: 50 91 | height:50 92 | //source: "../../images/png_images/circle_green_1.svg" 93 | source: din0status == 1 ? "../../images/png_images/circle_green_1.svg" : "../../images/png_images/circle_black.svg" 94 | } 95 | 96 | } 97 | 98 | Rectangle { 99 | id : rectdin1 100 | anchors.left: parent.left 101 | anchors.leftMargin: 60 102 | anchors.top: parent.top 103 | anchors.topMargin: 100 104 | width: 200 105 | height: 200 106 | color: "#00000000" 107 | 108 | Text { 109 | text: qsTr("DIN 1") 110 | anchors.verticalCenter : parent.verticalCenter 111 | color: "#00a5ff" 112 | font.pointSize: 16 113 | font.bold : true 114 | } 115 | AnimatedImage { 116 | anchors.verticalCenter : parent.verticalCenter 117 | anchors.left: parent.left 118 | anchors.leftMargin: 80 119 | smooth : true 120 | width: 50 121 | height:50 122 | source: din1status == 1 ? "../../images/png_images/circle_red_1.svg" : "../../images/png_images/circle_black.svg" 123 | 124 | } 125 | 126 | } 127 | Text { 128 | color: "#ffa500" 129 | font.pointSize: 12 130 | text: "Repaint color SVG image" 131 | anchors.left: parent.left 132 | anchors.leftMargin: 60 133 | anchors.top: parent.top 134 | anchors.topMargin: 260 135 | width: 150 136 | height: 100 137 | 138 | } 139 | Rectangle { 140 | id : rectdin2 141 | anchors.left: parent.left 142 | anchors.leftMargin: 60 143 | anchors.top: parent.top 144 | anchors.topMargin: 220 145 | width: 200 146 | height: 200 147 | color: "#00000000" 148 | //property color activeMenuColorRight: "#55aaff" 149 | Text { 150 | text: qsTr("DIN 2") 151 | anchors.verticalCenter : parent.verticalCenter 152 | color: "#00a5ff" 153 | font.pointSize: 16 154 | font.bold : true 155 | } 156 | Image { 157 | id: iconBtnDIN2 158 | source: "../../images/png_images/engine coolant.svg" 159 | anchors.verticalCenter : parent.verticalCenter 160 | anchors.left: parent.left 161 | anchors.leftMargin: 80 162 | smooth : true 163 | width: 50 164 | height:50 165 | } 166 | ColorOverlay{ 167 | anchors.fill: iconBtnDIN2 168 | source: iconBtnDIN2 169 | color: din2status == 1 ? "#ffff00" : "#202020" 170 | anchors.verticalCenter: parent.verticalCenter 171 | antialiasing: true 172 | width: 50 173 | height: 50 174 | } 175 | } 176 | 177 | Rectangle { 178 | id : rectdin3 179 | anchors.left: parent.left 180 | anchors.leftMargin: 60 181 | anchors.top: parent.top 182 | anchors.topMargin: 280 183 | width: 200 184 | height: 200 185 | color: "#00000000" 186 | visible : true 187 | Text { 188 | text: qsTr("DIN 3") 189 | anchors.verticalCenter : parent.verticalCenter 190 | color: "#00a5ff" 191 | font.pointSize: 16 192 | font.bold : true 193 | } 194 | Image { 195 | id: iconBtnDIN3 196 | source: "../../images/png_images/oil.svg" 197 | anchors.verticalCenter : parent.verticalCenter 198 | anchors.left: parent.left 199 | anchors.leftMargin: 80 200 | smooth : true 201 | width: 50 202 | height:50 203 | } 204 | ColorOverlay{ 205 | anchors.fill: iconBtnDIN3 206 | source: iconBtnDIN3 207 | color: din3status == 1 ? "#ff0000" : "#202020" 208 | anchors.verticalCenter: parent.verticalCenter 209 | antialiasing: true 210 | width: 50 211 | height: 50 212 | } 213 | } 214 | 215 | Text { 216 | color: "#ffa500" 217 | font.pointSize: 12 218 | text: "Blinked icon & text" 219 | anchors.left: parent.left 220 | anchors.leftMargin: 380 221 | anchors.top: parent.top 222 | anchors.topMargin: 65 223 | width: 150 224 | height: 100 225 | 226 | } 227 | Rectangle { 228 | id : rectdin4 229 | anchors.left: parent.left 230 | anchors.leftMargin: 380 231 | anchors.top: parent.top 232 | anchors.topMargin: 30 233 | width: 200 234 | height: 200 235 | color: "#00000000" 236 | visible : true 237 | Text { 238 | text: qsTr("DIN 4") 239 | anchors.verticalCenter : parent.verticalCenter 240 | color: "#00a5ff" 241 | font.pointSize: 16 242 | font.bold : true 243 | } 244 | Rectangle { 245 | id : rect 246 | anchors.fill: parent 247 | visible : din4status ==1 ? true : false 248 | color: "#00000000" 249 | Image { 250 | id: imagedin4 251 | anchors.verticalCenter : parent.verticalCenter 252 | anchors.left: parent.left 253 | anchors.leftMargin: 80 254 | smooth : true 255 | width: 50 256 | height:50 257 | source: "../../images/png_images/seat_belt.svg" 258 | } 259 | Timer { 260 | id: timerdin6 261 | running : true 262 | interval: 1000 263 | repeat: true 264 | onTriggered : imagedin4.visible = !imagedin4.visible 265 | } 266 | } 267 | } 268 | 269 | Rectangle { 270 | id : rectain6 271 | anchors.left: parent.left 272 | anchors.leftMargin: 380 273 | anchors.top: parent.top 274 | anchors.topMargin: 100 275 | width: 200 276 | height: 200 277 | color: "#00000000" 278 | visible : true 279 | Text { 280 | text: qsTr("DIN 5") 281 | anchors.verticalCenter : parent.verticalCenter 282 | color: "#00a5ff" 283 | font.pointSize: 16 284 | font.bold : true 285 | } 286 | Timer { 287 | id: timerain6 288 | running :din5status ==1 ? true : false 289 | interval: 1000 290 | repeat: true 291 | onTriggered : textain6.visible = !textain6.visible 292 | } 293 | Text { 294 | id: textain6 295 | text: qsTr("OVER SPEED") 296 | anchors.verticalCenter : parent.verticalCenter 297 | anchors.left: parent.left 298 | anchors.leftMargin: 80 299 | color: din5status ==1 ? "#FF0000" : "#00000000" 300 | font.pointSize: 16 301 | font.bold : true 302 | 303 | } 304 | 305 | } 306 | Text { 307 | color: "#ffa500" 308 | font.pointSize: 12 309 | text: "Change text & color" 310 | anchors.left: parent.left 311 | anchors.leftMargin: 380 312 | anchors.top: parent.top 313 | anchors.topMargin: 260 314 | width: 150 315 | height: 100 316 | 317 | } 318 | Rectangle { 319 | id : rectain7 320 | anchors.left: parent.left 321 | anchors.leftMargin: 380 322 | anchors.top: parent.top 323 | anchors.topMargin: 220 324 | width: 200 325 | height: 200 326 | color: "#00000000" 327 | visible : true 328 | Text { 329 | text: qsTr("DIN 6") 330 | anchors.verticalCenter : parent.verticalCenter 331 | color: "#00a5ff" 332 | font.pointSize: 16 333 | font.bold : true 334 | } 335 | Text { 336 | id: textain7 337 | text: din6status ==1 ? "OPEN" : "CLOSE" 338 | anchors.verticalCenter : parent.verticalCenter 339 | anchors.left: parent.left 340 | anchors.leftMargin: 80 341 | color: din6status ==1 ? "#E0E0E0" : "#91CF14" 342 | font.pointSize: 16 343 | font.bold : true 344 | } 345 | 346 | } 347 | 348 | Rectangle { 349 | id : rectain8 350 | anchors.left: parent.left 351 | anchors.leftMargin: 380 352 | anchors.top: parent.top 353 | anchors.topMargin: 290 354 | width: 200 355 | height: 200 356 | color: "#00000000" 357 | visible : true 358 | Text { 359 | text: qsTr("DIN 7") 360 | anchors.verticalCenter : parent.verticalCenter 361 | color: "#00a5ff" 362 | font.pointSize: 16 363 | font.bold : true 364 | } 365 | Text { 366 | id: textain8 367 | text: din7status ==1 ? "UP" : "DOWN" 368 | anchors.verticalCenter : parent.verticalCenter 369 | anchors.left: parent.left 370 | anchors.leftMargin: 80 371 | color: din7status ==1 ? "#E0E0E0" : "#FFA500" 372 | font.pointSize: 16 373 | font.bold : true 374 | } 375 | 376 | } 377 | } 378 | //######## END : Rectangle Container for PWM ######################## 379 | } 380 | //############ END : Main Rectangle page ########################### 381 | // 382 | Timer{ 383 | id:tmains 384 | interval: 250 385 | repeat: true 386 | running: true 387 | onTriggered: { 388 | din0status = backend.get_din0() 389 | din1status = backend.get_din1() 390 | din2status = backend.get_din2() 391 | din3status = backend.get_din3() 392 | din4status = backend.get_din4() 393 | din5status = backend.get_din5() 394 | din6status = backend.get_din6() 395 | din7status = backend.get_din7() 396 | } 397 | } 398 | 399 | //######## INI Space for connections ############################### 400 | Connections{ 401 | target: backend 402 | } 403 | //######## END : Space for connections############################## 404 | } 405 | 406 | -------------------------------------------------------------------------------- /Dashboard_qml/qml/pages/outputPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.15 2 | import QtQuick.Window 2.15 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Controls.Styles 1.4 5 | import QtQuick.Extras 1.4 6 | import QtQuick.Extras.Private 1.0 7 | import "../controls" 8 | 9 | 10 | Item { 11 | Rectangle { 12 | id: rectangle 13 | color: "#2c313c" 14 | anchors.fill: parent 15 | 16 | //################################################################## 17 | 18 | Label { 19 | id: labelLs1 20 | color: "#d0d0d0" 21 | text: qsTr("PIN 22") 22 | anchors.left: parent.left 23 | anchors.leftMargin: 50 24 | anchors.top: parent.top 25 | anchors.topMargin: 65 26 | height: 30 27 | width: 50 28 | horizontalAlignment: Text.AlignRight 29 | verticalAlignment: Text.AlignVCenter 30 | font.pointSize: 14 31 | } 32 | 33 | CustomSwitch{ 34 | id: ledSwitch1 35 | anchors.left: parent.left 36 | anchors.leftMargin: 120 37 | anchors.top: parent.top 38 | anchors.topMargin: 60 39 | backgroundHeight: 30 40 | backgroundWidth: 100 41 | onSwitched:{ 42 | if(on == true) 43 | backend.setPinoutput(22,'H'); 44 | else 45 | backend.setPinoutput(22,'L'); 46 | } 47 | } 48 | 49 | Label { 50 | id: labelLs2 51 | color: "#d0d0d0" 52 | text: qsTr(" PIN 23") 53 | anchors.left: parent.left 54 | anchors.leftMargin: 50 55 | anchors.top: parent.top 56 | anchors.topMargin: 135 57 | height: 30 58 | width: 50 59 | horizontalAlignment: Text.AlignRight 60 | verticalAlignment: Text.AlignVCenter 61 | font.pointSize: 14 62 | } 63 | CustomSwitch{ 64 | id: ledSwitch2 65 | anchors.left: parent.left 66 | anchors.leftMargin: 120 67 | anchors.top: parent.top 68 | anchors.topMargin: 130 69 | backgroundHeight: 30 70 | backgroundWidth: 100 71 | colorbg: "#F7A424" // "#39F724" 72 | onSwitched:{ 73 | if(on == true) 74 | backend.setPinoutput(23,'H'); 75 | else 76 | backend.setPinoutput(23,'L'); 77 | } 78 | } 79 | 80 | Label { 81 | id: labelLs3 82 | color: "#d0d0d0" 83 | text: qsTr(" PIN 24") 84 | anchors.left: parent.left 85 | anchors.leftMargin: 50 86 | anchors.top: parent.top 87 | anchors.topMargin: 205 88 | height: 30 89 | width: 50 90 | horizontalAlignment: Text.AlignRight 91 | verticalAlignment: Text.AlignVCenter 92 | font.pointSize: 14 93 | } 94 | CustomSwitch{ 95 | id: ledSwitch3 96 | anchors.left: parent.left 97 | anchors.leftMargin: 120 98 | anchors.top: parent.top 99 | anchors.topMargin: 200 100 | backgroundHeight: 30 101 | backgroundWidth: 100 102 | colorbg: "#f73924" 103 | onSwitched:{ 104 | if(on == true) 105 | backend.setPinoutput(24,'H'); 106 | else 107 | backend.setPinoutput(24,'L'); 108 | } 109 | } 110 | 111 | Label { 112 | id: labelLs4 113 | color: "#d0d0d0" 114 | text: qsTr(" PIN 25") 115 | anchors.left: parent.left 116 | anchors.leftMargin: 50 117 | anchors.top: parent.top 118 | anchors.topMargin: 275 119 | height: 30 120 | width: 50 121 | horizontalAlignment: Text.AlignRight 122 | verticalAlignment: Text.AlignVCenter 123 | font.pointSize: 14 124 | } 125 | CustomSwitch{ 126 | id: ledSwitch4 127 | anchors.left: parent.left 128 | anchors.leftMargin: 120 129 | anchors.top: parent.top 130 | anchors.topMargin: 270 131 | backgroundHeight: 30 132 | backgroundWidth: 100 133 | colorbg: "#00A5FF" // "#39F724" 134 | onSwitched:{ 135 | if(on == true) 136 | backend.setPinoutput(25,'H'); 137 | else 138 | backend.setPinoutput(25,'L'); 139 | } 140 | } 141 | 142 | //################################################################## 143 | 144 | SwitchDelegate { 145 | id: ledSwitch5 146 | text: qsTr("PIN 26") 147 | anchors.left: parent.left 148 | checked: false 149 | font.pointSize: 14 150 | height: 25 151 | anchors.top: parent.top 152 | anchors.leftMargin: 330 153 | anchors.topMargin: 67 154 | onCheckedChanged:{ 155 | if (checked){ 156 | backend.setPinoutput(26,'H'); 157 | }else { 158 | backend.setPinoutput(26,'L'); 159 | } 160 | } 161 | contentItem: Text { 162 | rightPadding: ledSwitch5.indicator.width + ledSwitch5.spacing 163 | text: ledSwitch5.text 164 | font: ledSwitch5.font 165 | opacity: enabled ? 1.0 : 0.3 166 | color: ledSwitch5.down ? "#39F724" : "#d0d0d0" 167 | elide: Text.ElideRight 168 | verticalAlignment: Text.AlignVCenter 169 | } 170 | 171 | indicator: Rectangle { 172 | implicitWidth: 58 173 | implicitHeight: 26 174 | x: ledSwitch5.width - width - ledSwitch5.rightPadding 175 | y: parent.height / 2 - height / 2 176 | radius: 13 177 | color: ledSwitch5.checked ? "#39F724" : "transparent" 178 | border.color: ledSwitch5.checked ? "#39F724" : "#cccccc" 179 | 180 | Rectangle { 181 | x: ledSwitch5.checked ? parent.width - width : 0 182 | width: 26 183 | height: 26 184 | radius: 13 185 | color: ledSwitch5.down ? "#c0c0c0" : "#f0f0f0" 186 | } 187 | } 188 | background: Rectangle { 189 | implicitWidth: 80 190 | implicitHeight: 40 191 | visible: ledSwitch5.down || ledSwitch5.highlighted 192 | color: "#00000000" 193 | } 194 | } 195 | 196 | SwitchDelegate { 197 | id: ledSwitch6 198 | text: qsTr("PIN 27") 199 | anchors.left: parent.left 200 | checked: false 201 | font.pointSize: 14 202 | height: 25 203 | anchors.top: parent.top 204 | anchors.leftMargin: 330 205 | anchors.topMargin: 137 206 | onCheckedChanged:{ 207 | if (checked){ 208 | backend.setPinoutput(27,'H'); 209 | }else { 210 | backend.setPinoutput(27,'L'); 211 | } 212 | } 213 | contentItem: Text { 214 | rightPadding: ledSwitch6.indicator.width + ledSwitch6.spacing 215 | text: ledSwitch6.text 216 | font: ledSwitch6.font 217 | opacity: enabled ? 1.0 : 0.3 218 | color: ledSwitch6.down ? "#F7A424" : "#d0d0d0" 219 | elide: Text.ElideRight 220 | verticalAlignment: Text.AlignVCenter 221 | } 222 | 223 | indicator: Rectangle { 224 | implicitWidth: 58 225 | implicitHeight: 26 226 | x: ledSwitch6.width - width - ledSwitch6.rightPadding 227 | y: parent.height / 2 - height / 2 228 | radius: 13 229 | color: ledSwitch6.checked ? "#F7A424" : "transparent" 230 | border.color: ledSwitch6.checked ? "#F7A424" : "#cccccc" 231 | 232 | Rectangle { 233 | x: ledSwitch6.checked ? parent.width - width : 0 234 | width: 26 235 | height: 26 236 | radius: 13 237 | color: ledSwitch6.down ? "#c0c0c0" : "#f0f0f0" 238 | } 239 | } 240 | background: Rectangle { 241 | implicitWidth: 80 242 | implicitHeight: 40 243 | visible: ledSwitch6.down || ledSwitch6.highlighted 244 | color: "#00000000" 245 | } 246 | } 247 | 248 | SwitchDelegate { 249 | id: ledSwitch7 250 | text: qsTr("") 251 | anchors.left: parent.left 252 | checked: false 253 | font.pointSize: 14 254 | height: 25 255 | rotation: -90 256 | anchors.top: parent.top 257 | anchors.leftMargin: 330 258 | anchors.topMargin: 257 259 | onCheckedChanged:{ 260 | if (checked){ 261 | backend.setPinoutput(28,'H'); 262 | }else { 263 | backend.setPinoutput(28,'L'); 264 | } 265 | } 266 | contentItem: Text { 267 | rightPadding: ledSwitch7.indicator.width + ledSwitch7.spacing 268 | text: ledSwitch7.text 269 | font: ledSwitch7.font 270 | opacity: enabled ? 1.0 : 0.3 271 | color: ledSwitch7.down ? "#f73924" : "#d0d0d0" 272 | elide: Text.ElideRight 273 | verticalAlignment: Text.AlignVCenter 274 | } 275 | 276 | indicator: Rectangle { 277 | implicitWidth: 58 278 | implicitHeight: 26 279 | x: ledSwitch7.width - width - ledSwitch7.rightPadding 280 | y: parent.height / 2 - height / 2 281 | radius: 13 282 | color: ledSwitch7.checked ? "#f73924" : "transparent" 283 | border.color: ledSwitch7.checked ? "#f73924" : "#cccccc" 284 | 285 | Rectangle { 286 | x: ledSwitch7.checked ? parent.width - width : 0 287 | width: 26 288 | height: 26 289 | radius: 13 290 | color: ledSwitch7.down ? "#c0c0c0" : "#f0f0f0" 291 | } 292 | } 293 | background: Rectangle { 294 | implicitWidth: 80 295 | implicitHeight: 40 296 | visible: ledSwitch7.down || ledSwitch7.highlighted 297 | color: "#00000000" 298 | } 299 | } 300 | Label { 301 | id: labelLs7 302 | anchors.left: parent.left 303 | anchors.top: parent.top 304 | anchors.leftMargin: 350 305 | anchors.topMargin: 200 306 | width: 50 307 | verticalAlignment: Text.AlignVCenter 308 | horizontalAlignment: Text.AlignHCenter 309 | font.pointSize: 14 310 | text: qsTr("PIN 28") 311 | color:"#C0C0C0" 312 | } 313 | 314 | SwitchDelegate { 315 | id: ledSwitch8 316 | text: qsTr("") 317 | anchors.left: parent.left 318 | checked: false 319 | font.pointSize: 14 320 | height: 25 321 | rotation : -90 322 | anchors.top: parent.top 323 | anchors.leftMargin: 400 324 | anchors.topMargin: 257 325 | onCheckedChanged:{ 326 | if (checked){ 327 | backend.setPinoutput(29,'H'); 328 | }else { 329 | backend.setPinoutput(29,'L'); 330 | } 331 | } 332 | contentItem: Text { 333 | rightPadding: ledSwitch8.indicator.width + ledSwitch8.spacing 334 | text: ledSwitch8.text 335 | font: ledSwitch8.font 336 | rotation : 90 337 | opacity: enabled ? 1.0 : 0.3 338 | color: ledSwitch8.down ? "#00aeff" : "#d0d0d0" 339 | elide: Text.ElideRight 340 | verticalAlignment: Text.AlignVCenter 341 | } 342 | 343 | indicator: Rectangle { 344 | implicitWidth: 58 345 | implicitHeight: 26 346 | x: ledSwitch8.width - width - ledSwitch8.rightPadding 347 | y: parent.height / 2 - height / 2 348 | radius: 13 349 | color: ledSwitch8.checked ? "#00aeff" : "transparent" 350 | border.color: ledSwitch8.checked ? "#00aeff" : "#cccccc" 351 | 352 | Rectangle { 353 | x: ledSwitch8.checked ? parent.width - width : 0 354 | width: 26 355 | height: 26 356 | radius: 13 357 | color: ledSwitch8.down ? "#c0c0c0" : "#f0f0f0" 358 | } 359 | } 360 | background: Rectangle { 361 | implicitWidth: 80 362 | implicitHeight: 40 363 | visible: ledSwitch8.down || ledSwitch8.highlighted 364 | color: "#00000000" 365 | } 366 | } 367 | Label { 368 | id: labelLs8 369 | anchors.left: parent.left 370 | anchors.top: parent.top 371 | anchors.leftMargin: 420 372 | anchors.topMargin: 200 373 | width: 50 374 | verticalAlignment: Text.AlignVCenter 375 | horizontalAlignment: Text.AlignHCenter 376 | font.pointSize: 14 377 | text: qsTr("PIN 29") 378 | color:"#C0C0C0" 379 | } 380 | 381 | Label { 382 | id: label1 383 | anchors.left: parent.left 384 | anchors.top: parent.top 385 | anchors.leftMargin: 30 386 | anchors.topMargin: 20 387 | width: 200 388 | verticalAlignment: Text.AlignVCenter 389 | horizontalAlignment: Text.AlignHCenter 390 | font.pointSize: 14 391 | text: qsTr("Animated SW") 392 | color:"#00a5ff" 393 | } 394 | Label { 395 | id: label2 396 | anchors.left: parent.left 397 | anchors.top: parent.top 398 | anchors.leftMargin: 300 399 | anchors.topMargin: 20 400 | width: 200 401 | verticalAlignment: Text.AlignVCenter 402 | horizontalAlignment: Text.AlignHCenter 403 | font.pointSize: 14 404 | text: qsTr("Delegate SW") 405 | color:"#00a5ff" 406 | } 407 | 408 | 409 | //################################################################## 410 | 411 | } 412 | Connections{ 413 | target: backend 414 | } 415 | } 416 | 417 | 418 | /*##^## 419 | Designer { 420 | D{i:0;autoSize:true;height:480;width:640} 421 | } 422 | ##^##*/ 423 | -------------------------------------------------------------------------------- /Dashboard_qml/GUI_QML_main.pyw: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | ###### STANDAR QT LIBRARIES 3 | ######################################################################## 4 | import sys 5 | from PyQt5.QtCore import * 6 | from PyQt5.QtGui import * 7 | from PyQt5.QtQml import * 8 | from PyQt5.QtWidgets import * 9 | from PyQt5.QtQuick import * 10 | #from PyQt5.QtMultimedia import* # For use audio alarms 11 | from PyQt5.QtChart import* # pip install PyQtChart 12 | 13 | ######################################################################## 14 | ###### SPECIAL LIBRARIES 15 | ######################################################################## 16 | import os 17 | import random 18 | import math 19 | import serial.tools.list_ports 20 | 21 | ######################################################################## 22 | ###### MAIN CLASS 23 | ######################################################################## 24 | class MainWindow(QObject): 25 | 26 | ###### SIGNALS ##################################################### 27 | # Signal Set Name 28 | setName = pyqtSignal(str) 29 | 30 | # Signal Set Name 31 | setPage = pyqtSignal(str) 32 | 33 | # Signal Set Port selected 34 | setCom = pyqtSignal(str) 35 | 36 | # Signal Set Data 37 | printTime = pyqtSignal(str) 38 | printDate = pyqtSignal(str) 39 | valueGauge = pyqtSignal(str) 40 | printHour = pyqtSignal(str) 41 | 42 | # Signal Visible 43 | isVisible = pyqtSignal(bool) 44 | 45 | # Open File To Text Edit 46 | readText = pyqtSignal(str) 47 | 48 | #setPuerto = pyqtSignal(object) ## NOT 49 | setPuerto = pyqtSignal(list) 50 | 51 | # Text String 52 | textField = "" 53 | 54 | def __init__(self, parent=None): 55 | super().__init__(parent) 56 | self.app = QApplication(sys.argv) 57 | self.app.setWindowIcon(QIcon("images/chip.ico")) 58 | self.engine = QQmlApplicationEngine(self) 59 | self.engine.rootContext().setContextProperty("backend", self) 60 | self.engine.load(QUrl("qml/main.qml")) 61 | 62 | #### SETUP CUSTOM ############################################## 63 | self.setupData() 64 | self.comSerialok = 0 65 | #self.nodin = [0,0,0,0] 66 | self.iniClock() 67 | sys.exit(self.app.exec_()) 68 | 69 | #################################################################### 70 | ###### CLOCK TIME 71 | #################################################################### 72 | def iniClock(self): 73 | self.timer = QTimer() 74 | self.timer.timeout.connect(lambda: self.setTime()) 75 | self.timer.start(1000) 76 | 77 | def setTime(self): 78 | current_time = QTime.currentTime() 79 | time = current_time.toString('HH:mm:ss') 80 | date = QDate.currentDate().toString(Qt.ISODate) 81 | formatDate= 'Now is '+date+' '+time 82 | 83 | numTest = str(random.randint(10,100)) 84 | self.valueGauge.emit(numTest) 85 | self.printTime.emit(formatDate) 86 | self.printDate.emit(date) 87 | self.printHour.emit(time) 88 | 89 | ###### Setup data registers to transfer to QML ################### 90 | def setupData(self): 91 | self.adc1 = 0 92 | self.adc2 = 0 93 | self.adc3 = 0 94 | self.adc4 = 0 95 | self.adc5 = 0 96 | self.adc6 = 0 97 | self.adc7 = 0 98 | self.adc8 = 0 99 | self.digitalsIn0 = 0 100 | self.digitalsIn1 = 0 101 | self.digitalsIn2 = 0 102 | self.digitalsIn3 = 0 103 | self.digitalsIn4 = 0 104 | self.digitalsIn5 = 0 105 | self.digitalsIn6 = 0 106 | self.digitalsIn7 = 0 107 | 108 | ###### Function Set Name To Page ################################# 109 | @pyqtSlot(str) 110 | def namePage(self, pagex): 111 | self.setPage.emit(pagex) 112 | 113 | #################################################################### 114 | # SELECT PORT & START COMMUNICATION 115 | #################################################################### 116 | 117 | ###### Description NAME HARDWARE COM PORTS ###################### 118 | @pyqtSlot(result=list) 119 | def personsList(self): 120 | return [port.device+" "+port.description for port in serial.tools.list_ports.comports()] 121 | 122 | ###### Number COM port available ################################ 123 | @pyqtSlot(result=QVariant) 124 | def get_port_list_info(self): 125 | return [port.device for port in serial.tools.list_ports.comports()] 126 | 127 | ###### Select COM PORT TO BE USED ################################# 128 | @pyqtSlot(str,int) 129 | def setPortCom(self, port, speed): 130 | baudrate = int(speed) 131 | try: 132 | self.ser = serial.Serial( 133 | port, 134 | baudrate, 135 | timeout=1, 136 | parity=serial.PARITY_NONE, 137 | stopbits=serial.STOPBITS_ONE, 138 | bytesize=serial.EIGHTBITS 139 | ) 140 | if self.ser.is_open: 141 | #print("Set PORT COM :", port, speed) 142 | self.comSerialok = 1 143 | self.iniSampler() 144 | 145 | except : 146 | print("PUERTO SERIAL NO RESPONDE") 147 | #sys.exit(-1) 148 | 149 | ###### Close serial port ########################################### 150 | @pyqtSlot(int) 151 | def closePort(self, value): 152 | self.comSerialok = 0 153 | self.ser.close() 154 | #print("Successfully closed serial port") 155 | 156 | #################################################################### 157 | ###### SAMPLER DATA 158 | #################################################################### 159 | def iniSampler(self): 160 | self.temporizador = QTimer() 161 | self.temporizador.timeout.connect(self.readData) 162 | self.temporizador.start(200) 163 | 164 | #################################################################### 165 | # READ DATA FROM ARDUINO, ANALOGS AIN & DIGITALS IN. 166 | #################################################################### 167 | def readData(self): 168 | if self.comSerialok: 169 | data = self.ser.read(1) 170 | n = self.ser.inWaiting() 171 | while n: 172 | data = data + self.ser.read(n) 173 | n = self.ser.inWaiting() 174 | ####### READ ANALOGS INPUTS ARDUINO 175 | st1=data[0]*256+data[1] 176 | st2=data[2]*256+data[3] 177 | st3=data[4]*256+data[5] 178 | st4=data[6]*256+data[7] 179 | st5=data[8]*256+data[9] 180 | st6=data[10]*256+data[11] 181 | st7=data[12]*256+data[13] 182 | st8=data[14]*256+data[15] 183 | #print (st1," ",st2," ",st3," ",st4) 184 | self.adc1 = st1 185 | self.adc2 = st2 186 | self.adc3 = st3 187 | self.adc4 = st4 188 | self.adc5 = st5 189 | self.adc6 = st6 190 | self.adc7 = st7 191 | self.adc8 = st8 192 | 193 | ######## READ DIGITAL INPUTS ARDUINO 194 | Din1=data[16]*256+data[17] 195 | Din2=data[18]*256+data[19] 196 | Din3=data[20]*256+data[21] 197 | Din4=data[22]*256+data[23] 198 | Din5=data[24]*256+data[25] 199 | Din6=data[26]*256+data[27] 200 | Din7=data[28]*256+data[29] 201 | Din8=data[30]*256+data[31] 202 | #print (Din1," ",Din2," ",Din3," ",Din4) 203 | 204 | # check the bit 1 for true and 0 false 205 | self.digitalsIn0 = Din1&1 206 | self.digitalsIn1 = Din2&1 207 | self.digitalsIn2 = Din3&1 208 | self.digitalsIn3 = Din4&1 209 | self.digitalsIn4 = Din5&1 210 | self.digitalsIn5 = Din6&1 211 | self.digitalsIn6 = Din7&1 212 | self.digitalsIn7 = Din8&1 213 | 214 | #################################################################### 215 | # REFERENCE TIME FOR GRAPHICS : VOLATILE CHART 216 | #################################################################### 217 | @pyqtSlot(result=int) 218 | def get_tiempo(self): 219 | date_time = QDateTime.currentDateTime() 220 | unixTIME = date_time.toSecsSinceEpoch() 221 | #unixTIMEx = date_time.currentMSecsSinceEpoch() 222 | return unixTIME 223 | 224 | #################################################################### 225 | # Set ON/OFF output FOR ARDUINO 226 | #################################################################### 227 | @pyqtSlot('int','QString') 228 | def setPinoutput(self, pin, value): 229 | dataled=str(pin)+value 230 | #print (dataled) 231 | if self.comSerialok: 232 | self.ser.write(dataled.encode()) 233 | else : 234 | pass 235 | #print("Set PIN OUTPUT :", pin, value) 236 | 237 | #################################################################### 238 | # Set PWM output FOR ARDUINO 239 | #################################################################### 240 | @pyqtSlot('QString','QString') 241 | def setPwm(self, pin, value): 242 | datapinpwm =pin+value 243 | #print (datapinpwm) 244 | if self.comSerialok: 245 | self.ser.write((pin+value).encode()) 246 | else: 247 | pass 248 | #print("Set PWM: PIN", pin, value) 249 | 250 | #################################################################### 251 | # SEND DATA FROM PYTHON TO QML: DIGITAL INPUTS 252 | #################################################################### 253 | @pyqtSlot(result=int) 254 | def get_din0(self): 255 | return self.digitalsIn0 256 | 257 | @pyqtSlot(result=int) 258 | def get_din1(self): 259 | return self.digitalsIn1 260 | 261 | @pyqtSlot(result=int) 262 | def get_din2(self): 263 | return self.digitalsIn2 264 | 265 | @pyqtSlot(result=int) 266 | def get_din3(self): 267 | return self.digitalsIn3 268 | 269 | @pyqtSlot(result=int) 270 | def get_din4(self): 271 | return self.digitalsIn4 272 | 273 | @pyqtSlot(result=int) 274 | def get_din5(self): 275 | return self.digitalsIn5 276 | 277 | @pyqtSlot(result=int) 278 | def get_din6(self): 279 | return self.digitalsIn6 280 | 281 | @pyqtSlot(result=int) 282 | def get_din7(self): 283 | return self.digitalsIn7 284 | 285 | #################################################################### 286 | # SEND DATA FROM PYTHON : ANALOG INPUTS 287 | #################################################################### 288 | @pyqtSlot(result=float) 289 | def get_adc1(self): 290 | return self.adc1 291 | 292 | @pyqtSlot(result=float) 293 | def get_adc2(self): 294 | return self.adc2 295 | 296 | @pyqtSlot(result=float) 297 | def get_adc3(self): 298 | return self.adc3 299 | 300 | @pyqtSlot(result=float) 301 | def get_adc4(self): 302 | return self.adc4 303 | 304 | @pyqtSlot(result=float) 305 | def get_adc5(self): 306 | return self.adc5 307 | 308 | @pyqtSlot(result=float) 309 | def get_adc6(self): 310 | return self.adc6 311 | 312 | @pyqtSlot(result=float) 313 | def get_adc7(self): 314 | return self.adc7 315 | 316 | @pyqtSlot(result=float) 317 | def get_adc8(self): 318 | return self.adc8 319 | 320 | #################################################################### 321 | # SEND DATA FROM PYTHON TO CHART CALCULATED FUNCTION (CSV, RANDOM) 322 | #################################################################### 323 | @pyqtSlot(QObject) 324 | def update0(self, series): 325 | series.clear() 326 | for i in range(128): 327 | series.append(i, 45*(math.sin(0.05*3.1416*i))+ random.random()*8) 328 | 329 | @pyqtSlot(QObject) 330 | def update1(self, series): 331 | series.clear() 332 | for i in range(128): 333 | series.append(i, 20*(math.sin(0.075*3.1416*i))+ random.random()*15) 334 | 335 | @pyqtSlot(QObject) 336 | def update2(self, series): 337 | series.clear() 338 | for i in range(128): 339 | series.append(i, 25*(math.sin(0.105*3.1416*i))+ random.random()*12) 340 | 341 | @pyqtSlot(QObject) 342 | def update3(self, series): 343 | series.clear() 344 | for i in range(128): 345 | series.append(i, 30*(math.sin(0.035*3.1416*i))+ random.random()*17) 346 | 347 | #################################################################### 348 | # FUNCTIONS FOR PAGE SETTINGS 349 | #################################################################### 350 | 351 | ###### Function Set Name To Label ############################### 352 | @pyqtSlot(str) 353 | def welcomeText(self, name): 354 | self.setName.emit("Welcome, " + name) 355 | 356 | ###### Show / Hide Rectangle ###################################### 357 | @pyqtSlot(bool,int) 358 | def showHideRectangle(self, isChecked, number): 359 | #print("Is rectangle visible: ", isChecked, number) 360 | self.isVisible.emit(isChecked) 361 | 362 | 363 | #################################################################### 364 | ###### MAIN ROUTINE 365 | #################################################################### 366 | if __name__ == '__main__': 367 | main = MainWindow() 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | --------------------------------------------------------------------------------