aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuchinton Chakravarty <suchinton.2001@gmail.com>2024-09-15 23:31:58 +0530
committerSuchinton Chakravarty <suchinton.2001@gmail.com>2024-09-29 23:31:52 +0530
commit65d4619371979c8921ff155a6fe1d7de0e1d3598 (patch)
treedefb38b033c88338b609c4b9ecc0edd55cb23124
parentb0844193f37f477c9e7e509e0b4eaf221886192b (diff)
Add New Custom Gauges and CARLA playback refactored
- This commit adds new custom QML Gauges for Engine RPM, Speed, Fuel level and Coolant temp - Improve Exception handling for CARLA playback - Add the RPM and Speed Gauge elements - Update the functions resp. for updating their values - Fix Alignment of backgrounds, font size and progress bar - Update Half Gauge to have progress ticks - Add gauges to the main IC page Bug-AGL: SPEC-5161 Change-Id: I52274afb7ea95c812c539a0b21305ad078d5dadb Signed-off-by: Suchinton Chakravarty <suchinton.2001@gmail.com>
-rw-r--r--Main_Window.ui16
-rw-r--r--QMLWidgets/Full_Gauge/RPMGauge.qml165
-rw-r--r--QMLWidgets/Full_Gauge/SpeedGauge.qml202
-rw-r--r--QMLWidgets/Full_Gauge/assets/Ellipse 1.svg11
-rw-r--r--QMLWidgets/Full_Gauge/assets/Ellipse 5.svg24
-rw-r--r--QMLWidgets/Half_Gauge/CoolantGauge.qml150
-rw-r--r--QMLWidgets/Half_Gauge/FuelGauge.qml158
-rw-r--r--Scripts/record_playback.py1
-rw-r--r--Widgets/ICPage.py91
-rw-r--r--Widgets/Keypad.py53
-rw-r--r--requirements.txt4
-rw-r--r--ui/IC.ui822
-rw-r--r--ui/Keypad.ui316
13 files changed, 1504 insertions, 509 deletions
diff --git a/Main_Window.ui b/Main_Window.ui
index 71fe4a4..41500a8 100644
--- a/Main_Window.ui
+++ b/Main_Window.ui
@@ -9,10 +9,16 @@
<rect>
<x>0</x>
<y>0</y>
- <width>903</width>
- <height>705</height>
+ <width>1600</width>
+ <height>900</height>
</rect>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>1600</width>
+ <height>900</height>
+ </size>
+ </property>
<property name="palette">
<palette>
<active>
@@ -153,7 +159,7 @@
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
- <color alpha="255">
+ <color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
@@ -299,7 +305,7 @@
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
- <color alpha="255">
+ <color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
@@ -445,7 +451,7 @@
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
- <color alpha="255">
+ <color alpha="128">
<red>255</red>
<green>255</green>
<blue>255</blue>
diff --git a/QMLWidgets/Full_Gauge/RPMGauge.qml b/QMLWidgets/Full_Gauge/RPMGauge.qml
new file mode 100644
index 0000000..382731d
--- /dev/null
+++ b/QMLWidgets/Full_Gauge/RPMGauge.qml
@@ -0,0 +1,165 @@
+import QtQuick 2.9
+
+Item {
+ id: root
+ width: 400
+ height: 400
+
+ property real value: 0
+ property real minValue: 0
+ property real maxValue: 8000
+ property string unit: "RPM"
+
+ property color primaryColor: "#16CCBA"
+ property color secondaryColor: "#00000000"
+ property int animationDuration: 1000
+ property real startAngle: 0
+
+ Rectangle {
+ anchors.fill: parent
+ color: "#041F2B"
+ z: -1
+ }
+
+ Image {
+ id: background1
+ source: "./assets/Ellipse 5.svg"
+ rotation: 180
+ sourceSize.width: width
+ sourceSize.height: width
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ anchors.centerIn: parent
+ scale: 1
+ opacity: 0.7
+ z: 0
+ }
+
+ Image {
+ id: background2
+ source: "./assets/Ellipse 1.svg"
+ sourceSize.width: width
+ sourceSize.height: width
+ anchors.fill: parent
+ anchors.centerIn: parent
+ fillMode: Image.PreserveAspectFit
+ scale: 1
+ opacity: 0.7
+ z: 1
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+ antialiasing: true
+ property real degree: 0
+
+ onDegreeChanged: requestPaint()
+
+ onPaint: {
+ var ctx = getContext("2d")
+ var center = Qt.point(width / 2, height / 2)
+ var side = Math.min(width, height)
+ var radius = (side - side * 0.20) / 2
+ var startAngle = Math.PI * 3 / 4
+ var fullAngle = Math.PI * 3 / 2
+ var progressAngle = startAngle + (degree / 270) * fullAngle
+
+ ctx.reset()
+ ctx.lineCap = 'round'
+
+ ctx.lineWidth = side * 0.1
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, progressAngle)
+ ctx.strokeStyle = secondaryColor
+ ctx.stroke()
+
+ ctx.lineWidth = 20
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, progressAngle)
+ ctx.strokeStyle = primaryColor
+ ctx.stroke()
+
+ // draw tick marks
+ ctx.lineWidth = 10
+ ctx.strokeStyle = '#FFFFFF'
+ ctx.beginPath()
+ var tickCount = 2; // Number of tick marks
+ for (var i = 0; i < tickCount; i++) {
+ var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle)
+ var x1 = center.x + radius * Math.cos(angle)
+ var y1 = center.y + radius * Math.sin(angle)
+ var x2 = center.x + (radius - 20) * Math.cos(angle)
+ var y2 = center.y + (radius - 20) * Math.sin(angle)
+ ctx.moveTo(x1, y1)
+ ctx.lineTo(x2, y2)
+ }
+ ctx.stroke()
+ }
+ }
+
+ Text {
+ id: gaugeText
+ anchors.centerIn: parent
+ text: "0"
+ font.pixelSize: 0.2 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugeUnit
+ anchors.top: gaugeText.bottom
+ anchors.horizontalCenter: gaugeText.horizontalCenter
+
+ text: unit
+ font.pixelSize: 18
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Behavior on value {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ onValueChanged: updateGaugeValue(value)
+
+ function updateGaugeValue(value) {
+ canvas.degree = value * 270
+ gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0)
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ property bool isDragging: false
+ property real initialValue: 0
+
+ onEntered: cursorShape = Qt.PointingHandCursor
+ onPressed: {
+ isDragging = true
+ initialValue = root.value
+ }
+ onReleased: isDragging = false
+
+ onMouseXChanged: updateDragValue(mouse.x, mouse.y)
+ onMouseYChanged: updateDragValue(mouse.x, mouse.y)
+
+ function updateDragValue(x, y) {
+ if (!isDragging) return
+
+ var centerX = width / 2
+ var centerY = height / 2
+ var dx = x - centerX
+ var dy = centerY - y // Note: y-axis is inverted
+ var angle = Math.atan2(dy, dx) * (180 / Math.PI)
+
+ // Convert angle to gauge value (0 to 1)
+ var gaugeValue = (angle + 135) / 270 // Adjust based on your gauge's start angle
+ gaugeValue = Math.max(0, Math.min(gaugeValue, 1)) // Clamp value
+
+ root.value = gaugeValue
+ }
+ }
+}
diff --git a/QMLWidgets/Full_Gauge/SpeedGauge.qml b/QMLWidgets/Full_Gauge/SpeedGauge.qml
new file mode 100644
index 0000000..263e7f1
--- /dev/null
+++ b/QMLWidgets/Full_Gauge/SpeedGauge.qml
@@ -0,0 +1,202 @@
+import QtQuick 2.9
+
+Item {
+ id: root
+ width: 400
+ height: 400
+
+ property real value: 0
+ property real minValue: 0
+ property real maxValue: 240
+ property string unit: "Km/h"
+
+ property color primaryColor: "#16CCBA"
+ property color secondaryColor: "#00000000"
+ property int animationDuration: 500
+ property real startAngle: Math.PI * 3 / 4
+ property real fullAngle: Math.PI * 3 / 2
+
+ property real gaugeRadius: 0
+ property real tickLength: 0
+
+ Component.onCompleted: {
+ calculateGeometry();
+ }
+
+ onWidthChanged: calculateGeometry()
+ onHeightChanged: calculateGeometry()
+
+ function calculateGeometry() {
+ const side = Math.min(width, height);
+ gaugeRadius = (side - side * 0.20) / 2;
+ tickLength = gaugeRadius * 0.05;
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "#041F2B"
+ z: -1
+ }
+
+ Image {
+ id: background1
+ source: "./assets/Ellipse 5.svg"
+ rotation: 180
+ sourceSize.width: width
+ sourceSize.height: width
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ scale: 1
+ opacity: 0.7
+ z: 0
+ }
+
+ Image {
+ id: background2
+ source: "./assets/Ellipse 1.svg"
+ sourceSize.width: width
+ sourceSize.height: width
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ scale: 1
+ opacity: 0.7
+ z: 1
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+ antialiasing: true
+ property real degree: 0
+
+ onDegreeChanged: requestPaint()
+
+ onPaint: {
+ var ctx = getContext("2d");
+ var center = Qt.point(width / 2, height / 2);
+
+ ctx.reset();
+ ctx.lineCap = 'round';
+
+ drawBackground(ctx, center);
+ drawProgress(ctx, center, degree);
+ drawTicks(ctx, center);
+ drawProgressTick(ctx, center, degree);
+ }
+
+ function drawBackground(ctx, center) {
+ ctx.lineWidth = gaugeRadius * 0.1;
+ ctx.beginPath();
+ ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + fullAngle);
+ ctx.strokeStyle = secondaryColor;
+ ctx.stroke();
+ }
+
+ function drawProgress(ctx, center, progress) {
+ ctx.lineWidth = 20;
+ ctx.beginPath();
+ ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + (progress / 270) * fullAngle);
+ ctx.strokeStyle = primaryColor;
+ ctx.stroke();
+ }
+
+ function drawTicks(ctx, center) {
+ ctx.lineWidth = tickLength * 2
+ ctx.strokeStyle = '#FFFFFF'
+ ctx.beginPath()
+ const tickCount = 2
+ for (let i = 0; i < tickCount; i++) {
+ const angle = startAngle + (i / (tickCount - 1)) * fullAngle
+ const x1 = center.x + gaugeRadius * Math.cos(angle)
+ const y1 = center.y + gaugeRadius * Math.sin(angle)
+ const x2 = center.x + (gaugeRadius - tickLength) * Math.cos(angle)
+ const y2 = center.y + (gaugeRadius - tickLength) * Math.sin(angle)
+ ctx.moveTo(x1, y1)
+ ctx.lineTo(x2, y2)
+ }
+ ctx.stroke();
+ }
+
+ function drawProgressTick(ctx, center, progress) {
+
+ ctx.lineWidth = tickLength * 3
+ ctx.strokeStyle = '#FFFFFF'
+ ctx.beginPath()
+
+ const progressAngle = startAngle + (progress / 270) * fullAngle
+ const x1 = center.x + gaugeRadius * Math.cos(progressAngle)
+ const y1 = center.y + gaugeRadius * Math.sin(progressAngle)
+ const x2 = center.x + (gaugeRadius - tickLength * 1.5) * Math.cos(progressAngle)
+ const y2 = center.y + (gaugeRadius - tickLength * 1.5) * Math.sin(progressAngle)
+
+ ctx.moveTo(x1, y1)
+ ctx.lineTo(x2, y2)
+ ctx.stroke()
+ }
+ }
+
+ Text {
+ id: gaugeText
+ anchors.centerIn: parent
+ text: "0"
+ font.pixelSize: 0.2 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugeUnit
+ anchors.top: gaugeText.bottom
+ anchors.horizontalCenter: gaugeText.horizontalCenter
+ text: unit
+ font.pixelSize: 18
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Behavior on value {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ onValueChanged: updateGaugeValue(value)
+
+ function updateGaugeValue(value) {
+ canvas.degree = value * 270
+ gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0)
+ }
+
+ MouseArea {
+ id: dragArea
+ anchors.fill: parent
+ hoverEnabled: true
+
+ property bool isDragging: false
+ property real initialValue: 0
+
+ onEntered: cursorShape = Qt.PointingHandCursor
+ onPressed: {
+ isDragging = true
+ initialValue = root.value
+ }
+ onReleased: isDragging = false
+
+ onMouseXChanged: updateDragValue(mouse.x, mouse.y)
+ onMouseYChanged: updateDragValue(mouse.x, mouse.y)
+
+ function updateDragValue(x, y) {
+ if (!isDragging) return
+
+ const centerX = width / 2
+ const centerY = height / 2
+ const dx = x - centerX
+ const dy = centerY - y // Note: y-axis is inverted
+ const angle = Math.atan2(dy, dx) * (180 / Math.PI)
+
+ // Convert angle to gauge value (0 to 1)
+ let gaugeValue = (angle + 135) / 270
+ gaugeValue = Math.max(0, Math.min(gaugeValue, 1)) // Clamp value
+
+ root.value = gaugeValue
+ }
+ }
+}
diff --git a/QMLWidgets/Full_Gauge/assets/Ellipse 1.svg b/QMLWidgets/Full_Gauge/assets/Ellipse 1.svg
new file mode 100644
index 0000000..c2666d9
--- /dev/null
+++ b/QMLWidgets/Full_Gauge/assets/Ellipse 1.svg
@@ -0,0 +1,11 @@
+<svg width="400" height="400" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="200" cy="200" r="187.5" stroke="url(#paint0_linear_1_121)" stroke-width="25" stroke-dasharray="5 5"/>
+<defs>
+<linearGradient id="paint0_linear_1_121" x1="-4" y1="196" x2="407.5" y2="196" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9EFFD6"/>
+<stop offset="0.333683" stop-color="#E6FFB0" stop-opacity="0"/>
+<stop offset="0.675444" stop-color="#E6FFB0" stop-opacity="0"/>
+<stop offset="1" stop-color="#9EFFD6"/>
+</linearGradient>
+</defs>
+</svg>
diff --git a/QMLWidgets/Full_Gauge/assets/Ellipse 5.svg b/QMLWidgets/Full_Gauge/assets/Ellipse 5.svg
new file mode 100644
index 0000000..a4a07a2
--- /dev/null
+++ b/QMLWidgets/Full_Gauge/assets/Ellipse 5.svg
@@ -0,0 +1,24 @@
+<svg width="203" height="200" viewBox="0 0 203 200" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_ii_109_7)">
+<circle cx="101.5" cy="98.5" r="101.5" fill="#09111E"/>
+</g>
+<circle cx="101.5" cy="98.5" r="101" stroke="#A6FFFA"/>
+<defs>
+<filter id="filter0_ii_109_7" x="0" y="-13" width="203" height="223" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="10"/>
+<feGaussianBlur stdDeviation="10"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.625 0 0 0 0 0.99537 0 0 0 0 1 0 0 0 0.6 0"/>
+<feBlend mode="normal" in2="shape" result="effect1_innerShadow_109_7"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="-10"/>
+<feGaussianBlur stdDeviation="10"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.623529 0 0 0 0 0.996078 0 0 0 0 1 0 0 0 0.6 0"/>
+<feBlend mode="normal" in2="effect1_innerShadow_109_7" result="effect2_innerShadow_109_7"/>
+</filter>
+</defs>
+</svg>
diff --git a/QMLWidgets/Half_Gauge/CoolantGauge.qml b/QMLWidgets/Half_Gauge/CoolantGauge.qml
new file mode 100644
index 0000000..6e1d583
--- /dev/null
+++ b/QMLWidgets/Half_Gauge/CoolantGauge.qml
@@ -0,0 +1,150 @@
+import QtQuick 2.9
+
+Item {
+ id: root
+ width: 200
+ height: 200
+
+ property real value: 80
+ property real minValue: 0
+ property real maxValue: 120
+ property string unit: "°C"
+
+ property color primaryColor: "#16CCBA"
+ property color secondaryColor: "#00000000"
+ property int animationDuration: 500
+ property real startAngle: 0
+
+ Rectangle {
+ anchors.fill: parent
+ color: "#041F2B"
+ z: -1
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+ antialiasing: true
+ property real degree: 0
+
+ onDegreeChanged: requestPaint()
+
+ onPaint: {
+ var ctx = getContext("2d")
+ var center = Qt.point(width / 2, height / 2)
+ var side = Math.min(width, height)
+ var radius = (side - side * 0.25) / 2
+ var startAngle = Math.PI * 2 / 3
+ var fullAngle = Math.PI * 2 / 3
+ var progressAngle = startAngle + (degree / 270) * fullAngle
+
+ ctx.reset()
+ ctx.lineCap = 'square'
+
+ // background arc
+ ctx.lineWidth = 25
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle)
+ ctx.strokeStyle = '#000000'
+ ctx.stroke()
+
+ // fill arc
+ ctx.lineWidth = 15
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, progressAngle)
+ ctx.strokeStyle = primaryColor
+ ctx.stroke()
+
+ // draw tick marks
+ ctx.lineWidth = 5
+ ctx.strokeStyle = '#FFFFFF'
+ ctx.beginPath()
+ var tickCount = 2; // Number of tick marks
+ for (var i = 0; i < tickCount; i++) {
+ var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle)
+ var x1 = center.x + radius * Math.cos(angle)
+ var y1 = center.y + radius * Math.sin(angle)
+ var x2 = center.x + (radius - 10) * Math.cos(angle)
+ var y2 = center.y + (radius - 10) * Math.sin(angle)
+ ctx.moveTo(x1, y1)
+ ctx.lineTo(x2, y2)
+ }
+ ctx.stroke()
+ }
+ }
+
+ Text {
+ id: gaugeText
+ anchors.centerIn: parent
+ text: "0"
+ font.pixelSize: 0.3 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugePercentage
+ anchors.verticalCenter: gaugeText.verticalCenter
+ anchors.left: gaugeText.right
+ text: "%"
+ font.pixelSize: 0.15 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugeUnit
+ anchors.top: gaugeText.bottom
+ anchors.horizontalCenter: gaugeText.horizontalCenter
+
+ text: unit
+ font.pixelSize: 18
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Behavior on value {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ onValueChanged: updateGaugeValue(value)
+
+ function updateGaugeValue(value) {
+ canvas.degree = value * 270
+ gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0)
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ property bool isDragging: false
+ property real initialValue: 0
+
+ onEntered: cursorShape = Qt.PointingHandCursor
+ onPressed: {
+ isDragging = true
+ initialValue = root.value
+ }
+ onReleased: isDragging = false
+
+ onMouseXChanged: updateDragValue(mouse.x, mouse.y)
+ onMouseYChanged: updateDragValue(mouse.x, mouse.y)
+
+ function updateDragValue(x, y) {
+ if (!isDragging) return
+
+ var centerX = width / 2
+ var centerY = height / 2
+ var dx = x - centerX
+ var dy = centerY - y // Note: y-axis is inverted
+ var angle = Math.atan2(dy, dx) * (180 / Math.PI)
+
+ // Convert angle to gauge value (0 to 1)
+ var gaugeValue = (angle + 135) / 270; // Adjust based on your gauge's start angle
+ gaugeValue = Math.max(0, Math.min(gaugeValue, 1)); // Clamp value
+
+ root.value = gaugeValue;
+ }
+ }
+}
diff --git a/QMLWidgets/Half_Gauge/FuelGauge.qml b/QMLWidgets/Half_Gauge/FuelGauge.qml
new file mode 100644
index 0000000..21ac4cd
--- /dev/null
+++ b/QMLWidgets/Half_Gauge/FuelGauge.qml
@@ -0,0 +1,158 @@
+import QtQuick 2.9
+
+Item {
+ id: root
+ width: 200
+ height: 200
+
+ property real value: 80
+ property real minValue: 0
+ property real maxValue: 100
+ property string unit: "NA"
+
+ property color primaryColor: "#16CCBA"
+ property color secondaryColor: "#00000000"
+ property int animationDuration: 500
+ property real startAngle: 0
+
+ property var exposedFunction: updateGaugeUnit
+
+ Rectangle {
+ anchors.fill: parent
+ color: "#041F2B"
+ z: -1
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+ antialiasing: true
+ property real degree: 0
+
+ onDegreeChanged: requestPaint()
+
+ onPaint: {
+ var ctx = getContext("2d")
+ var center = Qt.point(width / 2, height / 2)
+ var side = Math.min(width, height)
+ var radius = (side - side * 0.25) / 2
+ var startAngle = Math.PI * 2 / 3
+ var fullAngle = Math.PI * 2 / 3
+ var progressAngle = startAngle + (degree / 270) * fullAngle
+
+ ctx.reset()
+ ctx.lineCap = 'square'
+
+ // background arc
+ ctx.lineWidth = 25
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle)
+ ctx.strokeStyle = '#000000'
+ ctx.stroke()
+
+ // fill arc
+ ctx.lineWidth = 15
+ ctx.beginPath()
+ ctx.arc(center.x, center.y, radius, startAngle, progressAngle)
+ ctx.strokeStyle = primaryColor
+ ctx.stroke()
+
+ // draw tick marks
+ ctx.lineWidth = 5
+ ctx.strokeStyle = '#FFFFFF'
+ ctx.beginPath()
+ var tickCount = 2; // Number of tick marks
+ for (var i = 0; i < tickCount; i++) {
+ var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle)
+ var x1 = center.x + radius * Math.cos(angle)
+ var y1 = center.y + radius * Math.sin(angle)
+ var x2 = center.x + (radius - 10) * Math.cos(angle)
+ var y2 = center.y + (radius - 10) * Math.sin(angle)
+ ctx.moveTo(x1, y1)
+ ctx.lineTo(x2, y2)
+ }
+ ctx.stroke()
+ }
+ }
+
+ Text {
+ id: gaugeText
+ anchors.centerIn: parent
+ text: "0"
+ font.pixelSize: 0.3 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugePercentage
+ // anchor this to the right of the gaugeText such that their baseline is aligned
+
+ anchors.verticalCenter: gaugeText.verticalCenter
+ anchors.left: gaugeText.right
+ text: "%"
+ font.pixelSize: 0.15 * Math.min(root.width, root.height)
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Text {
+ id: gaugeUnit
+ anchors.top: gaugeText.bottom
+ anchors.horizontalCenter: gaugeText.horizontalCenter
+
+ text: unit
+ font.pixelSize: 18
+ font.bold: true
+ color: "#FFFFFF"
+ }
+
+ Behavior on value {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ onValueChanged: updateGaugeValue(value)
+
+ function updateGaugeValue(value) {
+ canvas.degree = value * 270
+ gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0)
+ }
+
+ function updateGaugeUnit() {
+ gaugeUnit.text = unit
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+
+ property bool isDragging: false
+ property real initialValue: 0
+
+ onEntered: cursorShape = Qt.PointingHandCursor
+ onPressed: {
+ isDragging = true
+ initialValue = root.value
+ }
+ onReleased: isDragging = false
+
+ onMouseXChanged: updateDragValue(mouse.x, mouse.y)
+ onMouseYChanged: updateDragValue(mouse.x, mouse.y)
+
+ function updateDragValue(x, y) {
+ if (!isDragging) return
+
+ var centerX = width / 2
+ var centerY = height / 2
+ var dx = x - centerX
+ var dy = centerY - y // Note: y-axis is inverted
+ var angle = Math.atan2(dy, dx) * (180 / Math.PI)
+
+ // Convert angle to gauge value (0 to 1)
+ var gaugeValue = (angle + 135) / 270; // Adjust based on your gauge's start angle
+ gaugeValue = Math.max(0, Math.min(gaugeValue, 1)); // Clamp value
+
+ root.value = gaugeValue;
+ }
+ }
+}
diff --git a/Scripts/record_playback.py b/Scripts/record_playback.py
index e518356..5d3956e 100644
--- a/Scripts/record_playback.py
+++ b/Scripts/record_playback.py
@@ -139,3 +139,4 @@ def main():
if __name__ == "__main__":
main()
+
diff --git a/Widgets/ICPage.py b/Widgets/ICPage.py
index 213e74c..e3d4ddf 100644
--- a/Widgets/ICPage.py
+++ b/Widgets/ICPage.py
@@ -10,7 +10,8 @@ from PyQt6 import uic, QtCore, QtWidgets
from PyQt6.QtWidgets import QApplication
from PyQt6.QtGui import QIcon, QPixmap, QPainter
from PyQt6.QtCore import QObject, pyqtSignal
-from PyQt6.QtWidgets import QWidget
+from PyQt6.QtWidgets import QWidget, QFrame
+from PyQt6.QtQuickWidgets import QQuickWidget
import threading
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -31,6 +32,41 @@ from Scripts.record_playback import CAN_playback
import res_rc
from Widgets.animatedToggle import AnimatedToggle
+def Gauge(gaugeType):
+ """QWidget
+ This function creates a full gauge widget with the specified maximum value, current value, and unit.
+
+ Args:
+ - maxValue: The maximum value of the gauge.
+ - value: The current value of the gauge.
+ - unit: The unit of the gauge.
+
+ Returns:
+ - A QQuickWidget object representing the full gauge widget.
+ """
+
+ RPM_GaugeQML = os.path.join(current_dir, "../QMLWidgets/Full_Gauge/RPMGauge.qml")
+ Speed_GaugeQML = os.path.join(current_dir, "../QMLWidgets/Full_Gauge/SpeedGauge.qml")
+ Fuel_GaugeQML = os.path.join(current_dir, "../QMLWidgets/Half_Gauge/FuelGauge.qml")
+ Coolant_GaugeQML = os.path.join(current_dir, "../QMLWidgets/Half_Gauge/CoolantGauge.qml")
+
+ gauge = QQuickWidget()
+ if gaugeType == "RPM":
+ gauge.setSource(QtCore.QUrl(RPM_GaugeQML))
+
+ elif gaugeType == "Speed":
+ gauge.setSource(QtCore.QUrl(Speed_GaugeQML))
+
+ elif gaugeType == "Fuel":
+ gauge.setSource(QtCore.QUrl(Fuel_GaugeQML))
+
+ elif gaugeType == "Coolant":
+ gauge.setSource(QtCore.QUrl(Coolant_GaugeQML))
+
+ gauge.setResizeMode(QQuickWidget.ResizeMode.SizeRootObjectToView)
+
+ return gauge
+
class IC_Paths():
def __init__(self):
self.speed = "Vehicle.Speed"
@@ -42,7 +78,6 @@ class IC_Paths():
self.coolantTemp = "Vehicle.Powertrain.CombustionEngine.ECT"
self.selectedGear = "Vehicle.Powertrain.Transmission.SelectedGear"
-
class ICWidget(Base, Form):
"""
This class represents the ICWidget which is a widget for the AGL Demo Control Panel.
@@ -68,7 +103,9 @@ class ICWidget(Base, Form):
header_frame = self.findChild(QWidget, "header_frame")
layout = header_frame.layout()
- self.IC_Frame = self.findChild(QWidget, "frame_1")
+ self.Frame_1 = self.findChild(QWidget, "frame_1")
+ self.Fuel_Gauge_Frame = self.findChild(QFrame, "fuel_gauge_frame")
+ self.Coolant_Gauge_Frame = self.findChild(QFrame, "coolant_gauge_frame")
self.Script_toggle = AnimatedToggle()
@@ -93,23 +130,41 @@ class ICWidget(Base, Form):
self.driveGroupBtns.buttonClicked.connect(self.driveBtnClicked)
- self.Speed_slider.valueChanged.connect(self.update_Speed_monitor)
+ Speed_Gauge_Placeholder = self.findChild(QWidget, "Speed_Gauge_Placeholder")
+ self.Speed_Gauge = Gauge("Speed")
+ self.Frame_1.layout().replaceWidget(Speed_Gauge_Placeholder, self.Speed_Gauge)
+
+ self.Speed_slider.valueChanged.connect(self.update_Speed_gauge)
self.Speed_slider.setMinimum(0)
self.Speed_slider.setMaximum(240)
+ RPM_Gauge_Placeholder = self.findChild(QWidget, "RPM_Gauge_Placeholder")
+ self.RPM_Gauge = Gauge("RPM")
+ self.Frame_1.layout().replaceWidget(RPM_Gauge_Placeholder, self.RPM_Gauge)
+
self.RPM_slider.valueChanged.connect(self.update_RPM_monitor)
self.RPM_slider.setMinimum(0)
self.RPM_slider.setMaximum(8000)
+ fuel_Gauge_Placeholder = self.findChild(QWidget, "fuel_Gauge_Placeholder")
+ self.Fuel_Gauge = Gauge("Fuel")
+ self.Fuel_Gauge_Frame.layout().replaceWidget(fuel_Gauge_Placeholder, self.Fuel_Gauge)
+
+ coolant_Gauge_Placeholder = self.findChild(QWidget, "coolant_Gauge_Placeholder")
+ self.Coolant_Gauge = Gauge("Coolant")
+ self.Coolant_Gauge_Frame.layout().replaceWidget(coolant_Gauge_Placeholder, self.Coolant_Gauge)
+
+ self.mousePressEvent = lambda event: print("Mouse Pressed")
+ self.mouseReleaseEvent = lambda event: print("Mouse Released")
+
+ self.Coolant_Gauge.mousePressEvent = self.mousePressEvent
+ self.Coolant_Gauge.mouseReleaseEvent = self.mouseReleaseEvent
+
self.coolantTemp_slider.valueChanged.connect(
self.update_coolantTemp_monitor)
self.fuelLevel_slider.valueChanged.connect(
self.update_fuelLevel_monitor)
- self.accelerationBtn.pressed.connect(self.accelerationBtnPressed)
- self.accelerationBtn.released.connect(self.accelerationBtnReleased)
-
- # make both buttons checkable
self.Script_toggle.clicked.connect(self.handle_Script_toggle)
self.leftIndicatorBtn.setCheckable(True)
self.rightIndicatorBtn.setCheckable(True)
@@ -125,12 +180,13 @@ class ICWidget(Base, Form):
def set_Vehicle_RPM(self, rpm):
self.RPM_slider.setValue(rpm)
- def update_Speed_monitor(self):
+ def update_Speed_gauge(self):
"""
Updates the speed monitor with the current speed value.
"""
speed = int(self.Speed_slider.value())
- self.Speed_monitor.display(speed)
+ speed = speed / 240
+ self.Speed_Gauge.rootObject().setProperty('value', speed)
if not self.simulator_running:
try:
self.kuksa_client.set(self.IC.speed, str(speed), 'value')
@@ -142,7 +198,8 @@ class ICWidget(Base, Form):
Updates the RPM monitor with the current RPM value.
"""
rpm = int(self.RPM_slider.value())
- self.RPM_monitor.display(rpm)
+ rpm = rpm / 8000
+ self.RPM_Gauge.rootObject().setProperty('value', rpm)
if not self.simulator_running:
try:
self.kuksa_client.set(self.IC.engineRPM, str(rpm), 'value')
@@ -154,6 +211,7 @@ class ICWidget(Base, Form):
Updates the coolant temperature monitor with the current coolant temperature value.
"""
coolantTemp = int(self.coolantTemp_slider.value())
+ self.Coolant_Gauge.rootObject().setProperty('value', coolantTemp/100)
try:
self.kuksa_client.set(
self.IC.coolantTemp, str(coolantTemp), 'value')
@@ -165,6 +223,8 @@ class ICWidget(Base, Form):
Updates the fuel level monitor with the current fuel level value.
"""
fuelLevel = int(self.fuelLevel_slider.value())
+ self.Fuel_Gauge.rootObject().setProperty('value', fuelLevel/100)
+ print(self.Fuel_Gauge.rootObject().property('value'))
try:
self.kuksa_client.set(self.IC.fuelLevel, str(fuelLevel))
except Exception as e:
@@ -279,7 +339,7 @@ class ICWidget(Base, Form):
if self.Script_toggle.isChecked():
self.Speed_slider.setEnabled(False)
self.RPM_slider.setEnabled(False)
- self.accelerationBtn.setEnabled(False)
+ # self.accelerationBtn.setEnabled(False)
for button in self.driveGroupBtns.buttons():
button.setEnabled(False)
self.set_Vehicle_RPM(1000)
@@ -291,7 +351,7 @@ class ICWidget(Base, Form):
self.simulator_running = False
self.Speed_slider.setEnabled(True)
self.RPM_slider.setEnabled(True)
- self.accelerationBtn.setEnabled(True)
+ # self.accelerationBtn.setEnabled(True)
for button in self.driveGroupBtns.buttons():
button.setEnabled(True)
@@ -321,7 +381,7 @@ class ICWidget(Base, Form):
self.Speed_slider.setValue(self.current_speed)
self.RPM_slider.setValue(self.current_rpm)
- self.update_Speed_monitor()
+ self.update_Speed_gauge()
self.update_RPM_monitor()
def driveBtnClicked(self):
@@ -336,7 +396,7 @@ class ICWidget(Base, Form):
if checked_button in gear_mapping:
gear_value = gear_mapping[checked_button]
- self.accelerationBtn.setEnabled(True)
+ # self.accelerationBtn.setEnabled(True)
self.Speed_slider.setEnabled(checked_button != self.neutralBtn)
self.RPM_slider.setEnabled(True)
try:
@@ -346,7 +406,6 @@ class ICWidget(Base, Form):
else:
print("Unknown button checked!")
-
class AccelerationFns():
def calculate_speed(time, acceleration) -> int:
# acceleration = 60 / 5 # acceleration from 0 to 60 in 5 seconds
diff --git a/Widgets/Keypad.py b/Widgets/Keypad.py
new file mode 100644
index 0000000..ad0c17e
--- /dev/null
+++ b/Widgets/Keypad.py
@@ -0,0 +1,53 @@
+import os
+import sys
+from PyQt6 import uic
+from PyQt6.QtWidgets import QApplication, QWidget, QPushButton
+import requests
+from urllib.parse import urljoin
+
+current_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.dirname(current_dir))
+
+Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/Keypad.ui"))
+
+import res_rc
+
+class KeypadWidget(Base, Form):
+ def __init__(self, parent=None):
+ super(self.__class__, self).__init__(parent)
+ self.setupUi(self)
+ self.host = "localhost"
+ self.port = 8080
+
+ # Mapping of keys to API endpoints
+ self.key_endpoints = {
+ "Key_1": "/cgi-bin/flutter.cgi",
+ "Key_2": "/cgi-bin/qt.cgi",
+ "Key_3": "/cgi-bin/momi.cgi",
+ "Key_4": "/cgi-bin/bomb.cgi",
+ "Key_5": "", # This key won't do anything
+ }
+
+ # Connect all keys to the same slot
+ for key_name in self.key_endpoints.keys():
+ key_button = self.findChild(QPushButton, key_name)
+ key_button.clicked.connect(lambda _, x=key_name: self.trigger_api(x))
+
+ def trigger_api(self, key_name):
+ endpoint = self.key_endpoints[key_name]
+ if endpoint:
+ url = f"http://{self.host}:{self.port}{endpoint}"
+ try:
+ response = requests.get(url, timeout=5)
+ response.raise_for_status()
+ print(f"API triggered successfully: {url}")
+ except requests.exceptions.RequestException as e:
+ print(f"Error triggering API: {str(e)}")
+ else:
+ print("No action defined for this key.")
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = KeypadWidget()
+ w.show()
+ sys.exit(app.exec())
diff --git a/requirements.txt b/requirements.txt
index 490e913..ab78645 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,4 +5,6 @@ PySide6==6.7.1
PySide6_Addons==6.7.1
PySide6_Essentials==6.7.1
kuksa-client==0.4.0
-python-can>=4.2.2 \ No newline at end of file
+python-can>=4.2.2
+requests
+rich \ No newline at end of file
diff --git a/ui/IC.ui b/ui/IC.ui
index b337ef6..256eb81 100644
--- a/ui/IC.ui
+++ b/ui/IC.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>920</width>
- <height>800</height>
+ <width>1200</width>
+ <height>880</height>
</rect>
</property>
<property name="windowTitle">
@@ -166,33 +166,13 @@ QLCDNumber {
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" rowspan="2">
- <spacer name="horizontalSpacer_12">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="2" rowspan="2">
- <spacer name="horizontalSpacer_13">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="minimumSize">
<size>
<width>500</width>
@@ -206,84 +186,10 @@ QLCDNumber {
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_4">
- <item row="0" column="0">
- <widget class="QFrame" name="header_frame">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>50</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QFrame" name="frame_6">
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font>
- <family>Open Sans Extrabold</family>
- <pointsize>18</pointsize>
- <weight>75</weight>
- <italic>true</italic>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Instrument Cluster</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_6">
- <property name="font">
- <font>
- <pointsize>18</pointsize>
- <weight>75</weight>
- <italic>true</italic>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Demo Mode</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="demoToggle">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QFrame" name="frame_3">
+ <item row="2" column="0">
+ <widget class="QFrame" name="frame_1">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -297,7 +203,7 @@ QLCDNumber {
<property name="maximumSize">
<size>
<width>16777215</width>
- <height>150</height>
+ <height>16777215</height>
</size>
</property>
<property name="frameShape">
@@ -306,150 +212,83 @@ QLCDNumber {
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="4">
- <widget class="QPushButton" name="rightIndicatorBtn">
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../assets/res.qrc">
- <normaloff>:/Images/Images/right.png</normaloff>:/Images/Images/right.png</iconset>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="3" column="3" alignment="Qt::AlignBottom">
+ <widget class="QSlider" name="Speed_slider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="iconSize">
+ <property name="minimumSize">
<size>
- <width>60</width>
+ <width>0</width>
<height>60</height>
</size>
</property>
- </widget>
- </item>
- <item row="1" column="1">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
+ <property name="maximum">
+ <number>240</number>
</property>
- </spacer>
- </item>
- <item row="1" column="3">
- <spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ <property name="tickPosition">
+ <enum>QSlider::NoTicks</enum>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
+ <property name="tickInterval">
+ <number>0</number>
</property>
- </spacer>
+ </widget>
</item>
- <item row="1" column="0">
- <widget class="QPushButton" name="leftIndicatorBtn">
- <property name="acceptDrops">
- <bool>false</bool>
+ <item row="4" column="3" alignment="Qt::AlignHCenter|Qt::AlignTop">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="autoFillBackground">
- <bool>false</bool>
+ <property name="font">
+ <font>
+ <family>Open Sans</family>
+ <weight>75</weight>
+ <italic>true</italic>
+ <bold>true</bold>
+ </font>
</property>
<property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../assets/res.qrc">
- <normaloff>:/Images/Images/left.png</normaloff>:/Images/Images/left.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>60</width>
- <height>60</height>
- </size>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
+ <string>Speed (Kmph)</string>
</property>
</widget>
</item>
- <item row="1" column="2">
- <widget class="QPushButton" name="hazardBtn">
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../assets/res.qrc">
- <normaloff>:/Images/Images/hazard.png</normaloff>:/Images/Images/hazard.png</iconset>
+ <item row="2" column="3">
+ <widget class="QWidget" name="Speed_Gauge_Placeholder" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="iconSize">
- <size>
- <width>60</width>
- <height>60</height>
- </size>
+ <property name="autoFillBackground">
+ <bool>false</bool>
</property>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="3" column="0">
- <widget class="QFrame" name="frame_1">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>200</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>150</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="4" column="8" alignment="Qt::AlignHCenter">
+ <item row="4" column="4" alignment="Qt::AlignHCenter|Qt::AlignTop">
<widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="font">
<font>
<family>Open Sans</family>
@@ -463,50 +302,191 @@ QLCDNumber {
</property>
</widget>
</item>
- <item row="1" column="5" rowspan="2" colspan="2">
- <widget class="QLCDNumber" name="Speed_monitor">
+ <item row="0" column="2" colspan="4">
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="4">
+ <widget class="QWidget" name="RPM_Gauge_Placeholder" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4" alignment="Qt::AlignBottom">
+ <widget class="QSlider" name="RPM_slider">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="font">
- <font>
- <weight>50</weight>
- <italic>false</italic>
- <bold>false</bold>
- </font>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>60</height>
+ </size>
</property>
- <property name="layoutDirection">
- <enum>Qt::LeftToRight</enum>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="3">
+ <widget class="QFrame" name="frame_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="smallDecimalPoint">
- <bool>false</bool>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
</property>
- <property name="digitCount">
- <number>3</number>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>150</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
</property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
</property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="4">
+ <widget class="QPushButton" name="rightIndicatorBtn">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../assets/res.qrc">
+ <normaloff>:/Images/Images/right.png</normaloff>:/Images/Images/right.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>60</width>
+ <height>60</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="3">
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="leftIndicatorBtn">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../assets/res.qrc">
+ <normaloff>:/Images/Images/left.png</normaloff>:/Images/Images/left.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>60</width>
+ <height>60</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="hazardBtn">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../assets/res.qrc">
+ <normaloff>:/Images/Images/hazard.png</normaloff>:/Images/Images/hazard.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>60</width>
+ <height>60</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item row="1" column="1" rowspan="4" colspan="2">
- <widget class="QFrame" name="frame_2">
+ <item row="1" column="0" rowspan="4" colspan="2">
+ <widget class="QFrame" name="coolant_gauge_frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>0</number>
- </property>
+ <layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
@@ -519,8 +499,33 @@ QLCDNumber {
<property name="bottomMargin">
<number>4</number>
</property>
- <item>
+ <item row="1" column="1">
+ <widget class="QSlider" name="coolantTemp_slider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
<widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string/>
</property>
@@ -529,207 +534,51 @@ QLCDNumber {
</property>
</widget>
</item>
- <item>
- <widget class="QSlider" name="coolantTemp_slider">
+ <item row="0" column="0" colspan="2">
+ <widget class="QWidget" name="coolant_Gauge_Placeholder" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="minimumSize">
<size>
- <width>60</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="1" column="0" rowspan="4">
- <spacer name="horizontalSpacer_10">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="3" colspan="8">
- <spacer name="verticalSpacer_5">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>10</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="12" rowspan="4">
- <spacer name="horizontalSpacer_11">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="3" column="8">
- <widget class="QSlider" name="RPM_slider">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>60</height>
- </size>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="7" rowspan="4">
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="3" rowspan="4" colspan="2">
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="8" rowspan="2">
- <widget class="QLCDNumber" name="RPM_monitor">
+ <item row="1" column="6" rowspan="4" alignment="Qt::AlignRight">
+ <widget class="QFrame" name="fuel_gauge_frame">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="font">
- <font>
- <weight>50</weight>
- <bold>false</bold>
- </font>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="digitCount">
- <number>4</number>
- </property>
- <property name="segmentStyle">
- <enum>QLCDNumber::Flat</enum>
- </property>
- </widget>
- </item>
- <item row="4" column="5" alignment="Qt::AlignHCenter">
- <widget class="QLabel" name="label_4">
- <property name="font">
- <font>
- <family>Open Sans</family>
- <weight>75</weight>
- <italic>true</italic>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Speed (Kmph)</string>
- </property>
- </widget>
- </item>
- <item row="3" column="5">
- <widget class="QSlider" name="Speed_slider">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>60</height>
- </size>
- </property>
- <property name="font">
- <font>
- <weight>50</weight>
- <bold>false</bold>
- </font>
- </property>
- <property name="maximum">
- <number>240</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::NoTicks</enum>
- </property>
- <property name="tickInterval">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item row="1" column="9" rowspan="4">
- <spacer name="horizontalSpacer_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="11" rowspan="4">
- <widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <property name="spacing">
- <number>0</number>
- </property>
+ <layout class="QGridLayout" name="gridLayout_6">
<property name="bottomMargin">
<number>4</number>
</property>
- <item>
+ <item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QSlider" name="fuelLevel_slider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="minimumSize">
<size>
<width>60</width>
@@ -758,10 +607,10 @@ QLCDNumber {
</property>
</widget>
</item>
- <item>
+ <item row="1" column="1" alignment="Qt::AlignRight">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -785,95 +634,94 @@ QLCDNumber {
</property>
</widget>
</item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QWidget" name="fuel_Gauge_Placeholder" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="4" column="0">
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
+ <item row="0" column="0">
+ <widget class="QFrame" name="header_frame">
+ <property name="minimumSize">
<size>
- <width>20</width>
- <height>40</height>
+ <width>0</width>
+ <height>50</height>
</size>
</property>
- </spacer>
- </item>
- <item row="5" column="0">
- <widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item alignment="Qt::AlignTop">
- <widget class="QPushButton" name="accelerationBtn">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QFrame" name="frame_6">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
</property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>80</height>
- </size>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
</property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignRight">
+ <widget class="QLabel" name="label_6">
<property name="font">
<font>
- <family>Open Sans</family>
- <pointsize>16</pointsize>
+ <pointsize>18</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
- <string>Accelerate</string>
- </property>
- <property name="icon">
- <iconset>
- <normaloff>:/Misc_icons/Misc_icons/speed-up-fill.svg</normaloff>:/Misc_icons/Misc_icons/speed-up-fill.svg</iconset>
+ <string>Demo Mode</string>
</property>
- <property name="iconSize">
- <size>
- <width>60</width>
- <height>60</height>
- </size>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignRight">
+ <widget class="QCheckBox" name="demoToggle">
+ <property name="text">
+ <string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="6" column="0">
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="7" column="0">
+ <item row="4" column="0" alignment="Qt::AlignBottom">
<widget class="QFrame" name="gearSelector">
<property name="minimumSize">
<size>
diff --git a/ui/Keypad.ui b/ui/Keypad.ui
new file mode 100644
index 0000000..cda5e42
--- /dev/null
+++ b/ui/Keypad.ui
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HVAC</class>
+ <widget class="QWidget" name="HVAC">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>420</width>
+ <height>690</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">*{
+ border: none;
+ background-color: transparent;
+ background: none;
+ padding: 0;
+ margin: 0;
+ color: #fff;
+}
+
+#scrollAreaWidgetContents{
+ background-color: #131313 ; /* black */
+}
+
+#centralwidget{
+ background-color: #131313 ; /* black */
+}
+
+#centralwidget QPushButton{
+ background-color: #6C6C85 ; /* pastel purple */
+ padding: 5px 10px;
+ border-radius: 10px;
+}
+
+#centralwidget QPushButton:pressed {
+ background-color: #4BD7D6 ; /* light blue */
+}
+
+#centralwidget QSlider::groove:horizontal {
+ border: 1px solid #6C6C85 ; /* pastel purple */
+ height: 15px;
+ border-radius: 8px;
+}
+
+#centralwidget QSlider::sub-page:horizontal {
+ background-color: #4BD7D6 ; /* light blue */
+ height: 15px;
+ border-radius: 5px;
+}
+
+#centralwidget QSlider::handle:horizontal {
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
+ stop:0 #eee, stop:1 #ccc);
+ border: 1px solid #777;
+ width: 20px;
+ margin-top: -2px;
+ margin-bottom: -2px;
+ border-radius: 8px;
+}
+
+QSlider::sub-page:vertical {
+ background-color: #131313 ; /* black */
+ height: 20px;
+ width: 28px;
+ margin: 2px;
+ border: 1px solid #6C6C85 ; /* pastel purple */
+ border-radius: 8px;
+}
+
+QSlider::groove:vertical {
+ border-radius: 8px;
+ width: 28px;
+ margin: 2px;
+ border: 1px solid #6C6C85 ; /* pastel purple */
+ background-color: #4BD7D6 ; /* light blue */
+}
+QSlider::groove:vertical:hover {
+ background-color: rgb(55, 62, 76);
+}
+QSlider::handle:vertical {
+ background-color: #d5d5d5;
+ height: 15px;
+ width: 20px;
+ border-radius: 5px;
+}
+QSlider::handle:vertical:hover {
+ background-color: #6C6C85 ; /* pastel purple */
+}
+QSlider::handle:vertical:pressed {
+ background-color: #4BD7D6 ; /* light blue */
+}
+
+
+QScrollBar:horizontal {
+ min-width: 240px;
+ height: 13px;
+ }
+
+ QScrollBar:vertical {
+ min-height: 240px;
+ width: 13px;
+ }
+
+ QScrollBar::groove {
+ background: 2A2827; /* dark grey */
+ border-radius: 5px;
+ }
+
+ QScrollBar::handle {
+ background: #4BD7D6 ; /* light blue */
+ border-radius: 5px;
+ }
+
+ QScrollBar::handle:horizontal {
+ width: 25px;
+ }
+
+ QScrollBar::handle:vertical {
+ height: 25px; scrollAreaWidgetContents
+ }
+
+#leftControls{
+ background: #041F2B ; /* dark blue */
+ border-radius: 10px;
+}
+
+#rightControls{
+ background: #041F2B ; /* dark blue */
+ border-radius: 10px;
+}
+
+
+/*============================================*/
+
+QListWidget {
+ min-height: 150px;
+ max-height: 150px;
+ background-color: #131313 ; /* black */
+ border: 1px solid #6C6C85 ; /* pastel purple */
+ border-radius: 8px;
+}
+
+QListWidget::item {
+ height: 50px;
+ width: 50px;
+ border-radius: 8px;
+ text-align: center;
+}
+
+QListWidget::item:selected {
+ background-color: #4BD7D6 ; /* light blue */
+ border-radius: 8px;
+}
+
+QListWidget::item:selected:!active {
+ border-width: 0px;
+}
+
+QListWidget::item:selected:active {
+ background-color: #4BD7D6 ; /* light blue */
+}
+
+QListWidget::item:selected:!focus {
+ color: black;
+ border-width: 0px;
+}
+
+QListWidget::item:focus {
+ background-color: #6C6C85 ; /* pastel purple */
+}
+
+QListWidget::item:hover {
+ background-color: #6C6C85 ; /* pastel purple */
+}
+
+</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QFrame" name="centralwidget">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <widget class="QFrame" name="frame_2">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QPushButton" name="Key_2">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/Keypad_Images/keypad_icons/f2-unpressed.png</normaloff>:/Keypad_Images/keypad_icons/f2-unpressed.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="Key_3">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/Keypad_Images/keypad_icons/f3-unpressed.png</normaloff>:/Keypad_Images/keypad_icons/f3-unpressed.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="Key_1">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/Keypad_Images/keypad_icons/f1-unpressed.png</normaloff>:/Keypad_Images/keypad_icons/f1-unpressed.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QPushButton" name="Key_5">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/Keypad_Images/keypad_icons/f5-unpressed.png</normaloff>:/Keypad_Images/keypad_icons/f5-unpressed.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QPushButton" name="Key_4">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>:/Keypad_Images/keypad_icons/f4-unpressed.png</normaloff>:/Keypad_Images/keypad_icons/f4-unpressed.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <spacer name="horizontalSpacer">
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer name="verticalSpacer">
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../assets/res.qrc"/>
+ </resources>
+ <connections/>
+</ui>