aboutsummaryrefslogtreecommitdiffstats
path: root/Widgets
diff options
context:
space:
mode:
Diffstat (limited to 'Widgets')
-rw-r--r--Widgets/Dashboard.py76
-rw-r--r--Widgets/HVACPage.py11
-rw-r--r--Widgets/ICPage.py42
-rw-r--r--Widgets/SteeringCtrlPage.py14
-rw-r--r--Widgets/animatedToggle.py166
-rw-r--r--Widgets/settings.py35
6 files changed, 249 insertions, 95 deletions
diff --git a/Widgets/Dashboard.py b/Widgets/Dashboard.py
index 1992b14..9df290f 100644
--- a/Widgets/Dashboard.py
+++ b/Widgets/Dashboard.py
@@ -3,19 +3,17 @@
#
# SPDX-License-Identifier: Apache-2.0
-from PyQt5 import QtCore, QtWidgets
import os
import sys
-from PyQt5 import uic
-from PyQt5 import QtWidgets
-from PyQt5.QtWidgets import *
-from PyQt5.QtSvg import *
-from PyQt5.QtCore import pyqtSignal
-from PyQt5.QtGui import QIcon
-from PyQt5 import QtCore
-from PyQt5 import QtSvg
-
-from extras import config
+from PyQt6 import uic
+from PyQt6 import QtCore, QtWidgets
+from PyQt6 import QtWidgets
+from PyQt6.QtWidgets import *
+from PyQt6.QtSvg import *
+from PyQt6.QtCore import pyqtSignal
+from PyQt6.QtGui import QIcon
+from PyQt6.QtGui import QIcon
+from PyQt6.QtCore import QSize
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -28,6 +26,8 @@ Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/Dashboard.ui"))
# ========================================
+from extras import config
+import res_rc
class Dashboard(Base, Form):
"""
@@ -78,42 +78,34 @@ class Dashboard(Base, Form):
DashboardTiles.addButton(tile)
def set_icon(self, tile, icon_size):
- icon_mapping = {
- self.DB_IC_Tile: ":/Carbon_Icons/carbon_icons/meter.svg",
- self.DB_HVAC_Tile: ":/Carbon_Icons/carbon_icons/windy--strong.svg",
- self.DB_Steering_Tile: ":/Images/Images/steering-wheel.svg",
- self.DB_Settings_Tile: ":/Carbon_Icons/carbon_icons/settings.svg"
- }
- icon_mapping_disabled = {
- self.DB_IC_Tile: ":/Carbon_Icons/carbon_icons/meter-disabled.svg",
- self.DB_HVAC_Tile: ":/Carbon_Icons/carbon_icons/windy--strong-disabled.svg",
- self.DB_Steering_Tile: ":/Images/Images/steering-wheel-disabled.svg",
- self.DB_Settings_Tile: ":/Carbon_Icons/carbon_icons/settings.svg"
+ icon_mappings = {
+ self.DB_IC_Tile: {
+ "normal": ":/Carbon_Icons/carbon_icons/meter.svg",
+ "disabled": ":/Carbon_Icons/carbon_icons/meter-disabled.svg"
+ },
+ self.DB_HVAC_Tile: {
+ "normal": ":/Carbon_Icons/carbon_icons/windy--strong.svg",
+ "disabled": ":/Carbon_Icons/carbon_icons/windy--strong-disabled.svg"
+ },
+ self.DB_Steering_Tile: {
+ "normal": ":/Images/Images/steering-wheel.svg",
+ "disabled": ":/Images/Images/steering-wheel-disabled.svg"
+ },
+ self.DB_Settings_Tile: {
+ "normal": ":/Carbon_Icons/carbon_icons/settings.svg",
+ "disabled": ":/Carbon_Icons/carbon_icons/settings.svg" # Assuming the same icon for simplicity
+ }
}
+ icon_key = "disabled" if not tile.isEnabled() else "normal"
+ file_path = icon_mappings.get(tile, {}).get(icon_key)
- file = icon_mapping.get(tile)
- if file is None:
+ if not file_path:
return
- getsize = QtSvg.QSvgRenderer(file)
- svg_widget = QtSvg.QSvgWidget(file)
- svg_widget.setFixedSize(getsize.defaultSize()*2)
- svg_widget.setStyleSheet("background-color: transparent;")
- icon = QIcon(svg_widget.grab())
-
- file = icon_mapping_disabled.get(tile)
- if file is None:
- return
-
- getsize = QtSvg.QSvgRenderer(file)
- svg_widget = QtSvg.QSvgWidget(file)
- svg_widget.setFixedSize(getsize.defaultSize()*2)
- svg_widget.setStyleSheet("background-color: transparent;")
- icon.addPixmap(svg_widget.grab(), QIcon.Disabled, QIcon.Off)
-
+ icon = QIcon(file_path)
tile.setIcon(icon)
- tile.setIconSize(QtCore.QSize(icon_size, icon_size))
+ tile.setIconSize(QSize(icon_size, icon_size))
def tile_clicked(self, tile):
"""
@@ -139,4 +131,4 @@ if __name__ == '__main__':
app = QApplication(sys.argv)
w = Dashboard()
w.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())
diff --git a/Widgets/HVACPage.py b/Widgets/HVACPage.py
index 0c25c58..d101e15 100644
--- a/Widgets/HVACPage.py
+++ b/Widgets/HVACPage.py
@@ -3,11 +3,10 @@
#
# SPDX-License-Identifier: Apache-2.0
-from extras.KuksaClient import KuksaClient
import os
import sys
-from PyQt5 import uic
-from PyQt5.QtWidgets import QApplication, QListWidget, QSlider, QPushButton
+from PyQt6 import uic
+from PyQt6.QtWidgets import QApplication, QListWidget, QSlider, QPushButton
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -20,6 +19,8 @@ Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/HVAC.ui"))
# ========================================
+from extras.KuksaClient import KuksaClient
+import res_rc
class HVAC_Paths():
def __init__(self):
@@ -115,7 +116,7 @@ class HVACWidget(Base, Form):
def setTemperature(self, list_widget, path):
item = list_widget.currentItem()
if item is not None:
- list_widget.scrollToItem(item, 1)
+ list_widget.scrollToItem(item)
self.kuksa_client.set(path, item.text()[:-2], "targetValue")
print(item.text())
@@ -145,4 +146,4 @@ if __name__ == '__main__':
app = QApplication(sys.argv)
w = HVACWidget()
w.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())
diff --git a/Widgets/ICPage.py b/Widgets/ICPage.py
index 4a32211..f2e41a7 100644
--- a/Widgets/ICPage.py
+++ b/Widgets/ICPage.py
@@ -6,14 +6,11 @@
import os
import logging
import sys
-from PyQt5 import uic, QtCore, QtWidgets
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtGui import QIcon, QPixmap, QPainter
-from PyQt5.QtCore import QObject, pyqtSignal
-from PyQt5.QtWidgets import QWidget
-from qtwidgets import AnimatedToggle
-from extras.KuksaClient import KuksaClient
-from extras.VehicleSimulator import VehicleSimulator
+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
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -26,6 +23,10 @@ Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/IC.ui"))
# ========================================
+from extras.KuksaClient import KuksaClient
+from extras.VehicleSimulator import VehicleSimulator
+import res_rc
+from Widgets.animatedToggle import AnimatedToggle
class IC_Paths():
def __init__(self):
@@ -66,10 +67,7 @@ class ICWidget(Base, Form):
self.IC_Frame = self.findChild(QWidget, "frame_1")
- self.Script_toggle = AnimatedToggle(
- checked_color="#4BD7D6",
- pulse_checked_color="#00ffff"
- )
+ self.Script_toggle = AnimatedToggle()
layout.replaceWidget(self.demoToggle, self.Script_toggle)
self.demoToggle.deleteLater()
@@ -175,13 +173,13 @@ class ICWidget(Base, Form):
"""
hazardIcon = QPixmap(":/Images/Images/hazard.png")
painter = QPainter(hazardIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
+ painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
if self.hazardBtn.isChecked():
- color = QtCore.Qt.yellow
+ color = QtCore.Qt.GlobalColor.yellow
value = "true"
else:
- color = QtCore.Qt.black
+ color = QtCore.Qt.GlobalColor.black
value = "false"
painter.fillRect(hazardIcon.rect(), color)
@@ -204,13 +202,13 @@ class ICWidget(Base, Form):
"""
leftIndicatorIcon = QPixmap(":/Images/Images/left.png")
painter = QPainter(leftIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
+ painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
if self.leftIndicatorBtn.isChecked():
- color = QtCore.Qt.green
+ color = QtCore.Qt.GlobalColor.green
value = "true"
else:
- color = QtCore.Qt.black
+ color = QtCore.Qt.GlobalColor.black
value = "false"
painter.fillRect(leftIndicatorIcon.rect(), color)
@@ -228,13 +226,13 @@ class ICWidget(Base, Form):
"""
rightIndicatorIcon = QPixmap(":/Images/Images/right.png")
painter = QPainter(rightIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
+ painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
if self.rightIndicatorBtn.isChecked():
- color = QtCore.Qt.green
+ color = QtCore.Qt.GlobalColor.green
value = "true"
else:
- color = QtCore.Qt.black
+ color = QtCore.Qt.GlobalColor.black
value = "false"
painter.fillRect(rightIndicatorIcon.rect(), color)
@@ -371,4 +369,4 @@ if __name__ == '__main__':
app = QApplication(sys.argv)
w = ICWidget()
w.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())
diff --git a/Widgets/SteeringCtrlPage.py b/Widgets/SteeringCtrlPage.py
index 7e0a131..5eb486d 100644
--- a/Widgets/SteeringCtrlPage.py
+++ b/Widgets/SteeringCtrlPage.py
@@ -3,13 +3,10 @@
#
# SPDX-License-Identifier: Apache-2.0
-from . import settings
-import extras.FeedCAN as feed_can
-from extras.KuksaClient import KuksaClient
import os
import sys
-from PyQt5 import uic
-from PyQt5.QtWidgets import QApplication, QButtonGroup
+from PyQt6 import uic
+from PyQt6.QtWidgets import QApplication, QButtonGroup
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -24,6 +21,11 @@ Form, Base = uic.loadUiType(os.path.join(
# ========================================
+import extras.FeedCAN as feed_can
+from Widgets import settings
+from extras.KuksaClient import KuksaClient
+import res_rc
+
class Steering_Paths():
def __init__(self):
self.switches = {
@@ -142,4 +144,4 @@ if __name__ == '__main__':
app = QApplication(sys.argv)
w = SteeringCtrlWidget()
w.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())
diff --git a/Widgets/animatedToggle.py b/Widgets/animatedToggle.py
new file mode 100644
index 0000000..7cfe254
--- /dev/null
+++ b/Widgets/animatedToggle.py
@@ -0,0 +1,166 @@
+# Copyright (C) 2024 Suchinton Chakravarty
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import sys
+from PyQt6.QtGui import QColor, QPainter, QPainterPath, QBrush
+from PyQt6.QtCore import pyqtProperty, QPropertyAnimation, QPoint, QEasingCurve
+from PyQt6.QtWidgets import QApplication, QCheckBox
+
+
+class AnimatedToggle(QCheckBox):
+ """
+ A custom toggle switch widget with animation effects.
+
+ Inherits QCheckBox class from PyQt6.QtWidgets module.
+ """
+
+ bg_color = pyqtProperty(
+ QColor, lambda self: self._bg_color,
+ lambda self, col: setattr(self, '_bg_color', col))
+ circle_color = pyqtProperty(
+ QColor, lambda self: self._circle_color,
+ lambda self, col: setattr(self, '_circle_color', col))
+ active_color = pyqtProperty(
+ QColor, lambda self: self._active_color,
+ lambda self, col: setattr(self, '_active_color', col))
+ disabled_color = pyqtProperty(
+ QColor, lambda self: self._disabled_color,
+ lambda self, col: setattr(self, '_disabled_color', col))
+ circle_pos = pyqtProperty(
+ float, lambda self: self._circle_pos,
+ lambda self, pos: (setattr(self, '_circle_pos', pos), self.update()))
+ intermediate_bg_color = pyqtProperty(
+ QColor, lambda self: self._intermediate_bg_color,
+ lambda self, col: setattr(self, '_intermediate_bg_color', col))
+
+ def __init__(self, parent=None):
+ """
+ Constructs an AnimatedToggle object.
+
+ Parameters
+ ----------
+ parent : QWidget, optional
+ The parent widget of the toggle switch (default is None).
+
+ """
+ super().__init__(parent)
+ self._bg_color = QColor("#965D62")
+ self._circle_color = QColor("#DDD")
+ self._active_color = QColor('#4BD7D6')
+ self._disabled_color = QColor('#965D62')
+ self._circle_pos = None
+ self._intermediate_bg_color = None
+ self._animation_duration = 500 # milliseconds
+ self._user_checked = False
+
+ self.setFixedHeight(28)
+ self.stateChanged.connect(self.start_transition)
+
+ def setDuration(self, duration: int):
+ """
+ Sets the duration of the animation.
+
+ Parameters
+ ----------
+ duration : int
+ The duration of the animation in milliseconds.
+
+ """
+ self._animation_duration = duration
+
+ def update_pos_color(self, checked=None):
+ self._circle_pos = self.height() * (1.1 if checked else 0.1)
+ if self.isChecked():
+ self._intermediate_bg_color = self._active_color
+ else:
+ self._intermediate_bg_color = self._bg_color
+
+ def start_transition(self, state):
+ if not self._user_checked:
+ self.update_pos_color(state)
+ return
+ for anim in [self.create_animation, self.create_bg_color_animation]:
+ animation = anim(state)
+ animation.start()
+ self._user_checked = False
+
+ def mousePressEvent(self, event):
+ self._user_checked = True
+ super().mousePressEvent(event)
+
+ def create_animation(self, state):
+ return self._create_common_animation(state, b'circle_pos', self.height() * 0.1, self.height() * 1.1)
+
+ def create_bg_color_animation(self, state):
+ return self._create_common_animation(state, b'intermediate_bg_color', self._bg_color, self._active_color)
+
+ def _create_common_animation(self, state, prop, start_val, end_val):
+ animation = QPropertyAnimation(self, prop, self)
+ animation.setEasingCurve(QEasingCurve.Type.OutBounce)
+ animation.setDuration(self._animation_duration)
+ animation.setStartValue(start_val if state else end_val)
+ animation.setEndValue(end_val if state else start_val)
+ return animation
+
+ def showEvent(self, event):
+ super().showEvent(event)
+ self.update_pos_color(self.isChecked())
+
+ def resizeEvent(self, event):
+ self.update_pos_color(self.isChecked())
+
+ def sizeHint(self):
+ size = super().sizeHint()
+ size.setWidth(self.height() * 2)
+ return size
+
+ def hitButton(self, pos: QPoint):
+ return self.contentsRect().contains(pos)
+
+ def paintEvent(self, event):
+ """
+ Handles the paint event of the toggle switch.
+
+ Parameters
+ ----------
+ event : QPaintEvent
+ The paint event.
+
+ """
+ painter = QPainter(self)
+ painter.setRenderHint(QPainter.RenderHint.Antialiasing)
+
+ circle_color = QColor(
+ self.disabled_color if not self.isEnabled() else self.circle_color)
+ bg_color = QColor(self.disabled_color if not self.isEnabled() else self.intermediate_bg_color) \
+ if self.intermediate_bg_color is not None else QColor("transparent")
+
+ border_radius = self.height() / 2
+ toggle_width = self.height() * 2
+ toggle_margin = self.height() * 0.3
+ circle_size = self.height() * 0.8
+
+ if self.circle_pos is None:
+ self.update_pos_color(self.isChecked())
+
+ bg_path = QPainterPath()
+ bg_path.addRoundedRect(
+ 0, 0, toggle_width, self.height(), border_radius, border_radius)
+ painter.fillPath(bg_path, QBrush(bg_color))
+
+ circle = QPainterPath()
+ circle.addEllipse(self.circle_pos, self.height()
+ * 0.1, circle_size, circle_size)
+ painter.fillPath(circle, QBrush(circle_color))
+
+ self.setStyleSheet(f"background-color: {bg_color.name()};")
+
+ painter.end()
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = AnimatedToggle()
+ window.show()
+ sys.exit(app.exec())
diff --git a/Widgets/settings.py b/Widgets/settings.py
index 08f6a00..4adf72d 100644
--- a/Widgets/settings.py
+++ b/Widgets/settings.py
@@ -3,18 +3,16 @@
#
# SPDX-License-Identifier: Apache-2.0
-from extras import config
-import extras.Kuksa_Instance as kuksa_instance
+
import os
import sys
import time
-from PyQt5 import uic
-from PyQt5.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel, QComboBox, QStyledItemDelegate
-from qtwidgets import AnimatedToggle
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtCore import QThread
-from PyQt5 import QtGui
+from PyQt6.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel
+from PyQt6 import uic
+from PyQt6.QtWidgets import QWidget
+from PyQt6.QtCore import QThread
+from PyQt6 import QtGui
import logging
import can
@@ -24,6 +22,11 @@ current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(current_dir))
+from extras import config
+import extras.Kuksa_Instance as kuksa_instance
+from Widgets.animatedToggle import AnimatedToggle
+import res_rc
+
Form, Base = uic.loadUiType(os.path.join(
current_dir, "../ui/Settings_Window.ui"))
@@ -34,14 +37,6 @@ Form, Base = uic.loadUiType(os.path.join(
Steering_Signal_Type = "Kuksa"
Protocol = None
-def create_animated_toggle():
- return AnimatedToggle(
- checked_color="#4BD7D6",
- pulse_checked_color="#00ffff",
- pulse_unchecked_color= "#4BD7D6",
- )
-
-
class settings(Base, Form):
"""
A class representing the settings widget of the AGL Demo Control Panel.
@@ -64,8 +59,8 @@ class settings(Base, Form):
self.setupUi(self)
self.client = None
- self.SSL_toggle = create_animated_toggle()
- self.Protocol_toggle = create_animated_toggle()
+ self.SSL_toggle = AnimatedToggle()
+ self.Protocol_toggle = AnimatedToggle()
self.connectionStatus = self.findChild(QLabel, "connectionStatus")
self.connectionLogo = self.findChild(QLabel, "connectionLogo")
@@ -96,7 +91,7 @@ class settings(Base, Form):
GS_layout.replaceWidget(self.place_holder_toggle_1, self.SSL_toggle)
GS_layout.replaceWidget(
- self.place_holder_toggle_2, self.Protocol_toggle)
+ self.place_holder_toggle_2, self.Protocol_toggle)
self.place_holder_toggle_1.deleteLater()
self.place_holder_toggle_2.deleteLater()
@@ -294,4 +289,4 @@ if __name__ == '__main__':
app = QApplication(sys.argv)
w = settings()
w.show()
- sys.exit(app.exec_())
+ sys.exit(app.exec())