diff options
author | Suchinton <suchinton.2001@gmail.com> | 2024-06-02 21:44:04 +0530 |
---|---|---|
committer | Suchinton <suchinton.2001@gmail.com> | 2024-06-24 00:06:49 +0530 |
commit | b742c6d5b26c036addb2922e36d06dbea35c10f1 (patch) | |
tree | 36b6c2349e5b6ce93de40884c9d62bae442bb410 | |
parent | 31573c88e0ddefc3591bb7752b306601554ebbf2 (diff) |
Port AGL Demo Control Panel to Qt6
This commit includes the following changes:
V1:
- Migrated from PyQt5 to PyQt6/PySide6 with minor syntax adjustments.
- Removed the dependency on qtwidgets and extracted only the required animated toggle module, patching it to work with PyQt6.
- Updated the README to include new steps for compiling resources.
- Bumped QtPy from version 2.3.1 to 2.4.1
V2:
- Refactored set_icon function in Dashboard module to make use of QIcon directly
instead of using the QtSvg library (Invalid in PyQt6)
- Syntax changes in UI_Handeler to use PyQt6
V3:
- Update gitignore
- Remove dependency on qtpy
V4:
- Added new animated toggle button
- Refactored ICPage and Settings to use new toggle
- Updated Navigation Bar Animation to have Bounce effect using "OutBounce" QEasingCurve
Bug-AGL: SPEC-5161
Change-Id: I44499bb5165d5794af7e9aae3407ffae1f7e1928
Signed-off-by: Suchinton <suchinton.2001@gmail.com>
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Main_Window.ui | 3 | ||||
-rw-r--r-- | README.md | 16 | ||||
-rw-r--r-- | Widgets/Dashboard.py | 76 | ||||
-rw-r--r-- | Widgets/HVACPage.py | 11 | ||||
-rw-r--r-- | Widgets/ICPage.py | 42 | ||||
-rw-r--r-- | Widgets/SteeringCtrlPage.py | 14 | ||||
-rw-r--r-- | Widgets/animatedToggle.py | 166 | ||||
-rw-r--r-- | Widgets/settings.py | 35 | ||||
-rw-r--r-- | extras/KuksaClient.py | 6 | ||||
-rw-r--r-- | extras/UI_Handeler.py | 22 | ||||
-rw-r--r-- | extras/VehicleSimulator.py | 2 | ||||
-rw-r--r-- | main.py | 31 | ||||
-rw-r--r-- | requirements.txt | 11 |
14 files changed, 288 insertions, 150 deletions
@@ -1,3 +1,6 @@ *__pycache__ Widgets/.vssclient_history map.html +test/ +control-panel/ +res_rc.py
\ No newline at end of file diff --git a/Main_Window.ui b/Main_Window.ui index 7bfb0ef..71fe4a4 100644 --- a/Main_Window.ui +++ b/Main_Window.ui @@ -532,9 +532,6 @@ QStackedWidget{ <property name="tabShape"> <enum>QTabWidget::Rounded</enum> </property> - <property name="dockOptions"> - <set>QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set> - </property> <property name="unifiedTitleAndToolBarOnMac"> <bool>true</bool> </property> @@ -1,6 +1,6 @@ # AGL_Demo_Control_Panel -A PyQt5 application to simulate CAN Bus signals using Kuksa.val for the AGL Demo platform. This application is to be used in parallel to the relevant AGL Images or any application that subscribes to VSS signals using [Kuksa.val-server](https://github.com/eclipse/kuksa.val/tree/master/kuksa-val-server) or [Kuksa-databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker). +A PyQt6 application to simulate CAN Bus signals using Kuksa.val for the AGL Demo platform. This application is to be used in parallel to the relevant AGL Images or any application that subscribes to VSS signals using [Kuksa.val-server](https://github.com/eclipse/kuksa.val/tree/master/kuksa-val-server) or [Kuksa-databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker). ## # Installation @@ -14,24 +14,12 @@ A PyQt5 application to simulate CAN Bus signals using Kuksa.val for the AGL Demo ``` - Install the Python dependencies: - - _Note_: - If errors occure in Debian based/Rasbian OS during installation: - ```bash - $ nano requirements.txt - # -> Comment pyqt5 dependency using "#" - $ sudo apt install python3-pyqt5 python3-qtpy pyqt5-dev-tools python3-pyqt5.qtsvg -y - ``` - and skip to step 2 - - Step 1 ```bash $ python3 -m venv control-panel $ source control-panel/bin/activate - ``` - - Step 2 - ```bash $ pip3 install -r requirements.txt - $ pyrcc5 assets/res.qrc -o res_rc.py + $ pyside6-rcc assets/res.qrc -o res_rc.py ``` ## # Usage 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()) diff --git a/extras/KuksaClient.py b/extras/KuksaClient.py index 504e21c..772fd50 100644 --- a/extras/KuksaClient.py +++ b/extras/KuksaClient.py @@ -4,8 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 import logging -from PyQt5.QtCore import QThread -from PyQt5.QtCore import pyqtSignal +from PyQt6.QtCore import QThread +from PyQt6.QtCore import pyqtSignal from . import Kuksa_Instance as kuksa_instance import threading @@ -103,7 +103,7 @@ class KuksaClient(QThread): logging.error(f"Error sending values to kuksa {e}") threading.Thread(target=self.set_instance).start() - def setValues(self, values : dict[str, any] = None): + def setValues(self, values: dict[str, any] = None): """ Sets VSS values. diff --git a/extras/UI_Handeler.py b/extras/UI_Handeler.py index 05a351d..911f5ff 100644 --- a/extras/UI_Handeler.py +++ b/extras/UI_Handeler.py @@ -15,16 +15,16 @@ """ from main import * -from PyQt5 import QtCore -from PyQt5.QtCore import QPropertyAnimation -from PyQt5.QtWidgets import QWidget -from PyQt5.QtCore import QEasingCurve -from PyQt5.QtWidgets import QGraphicsOpacityEffect +from PyQt6 import QtCore +from PyQt6.QtCore import QPropertyAnimation +from PyQt6.QtWidgets import QWidget +from PyQt6.QtCore import QEasingCurve +from PyQt6.QtWidgets import QGraphicsOpacityEffect from kuksa_client.grpc import Field, SubscribeEntry, View from kuksa_client.grpc.aio import VSSClient -from PyQt5.QtCore import pyqtSignal +from PyQt6.QtCore import pyqtSignal +from PyQt6.QtCore import QThread import asyncio -from PyQt5.QtCore import QThread import pathlib import logging import json @@ -91,7 +91,7 @@ class UI_Handeler(MainWindow): def fullscreen(self): self.headerContainer.hide() - self.setAttribute(QtCore.Qt.WA_TranslucentBackground, False) + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, False) self.showFullScreen() def block_updates(): @@ -117,7 +117,7 @@ class UI_Handeler(MainWindow): self.animation.setDuration(400) self.animation.setStartValue(height) self.animation.setEndValue(heightExtended) - self.animation.setEasingCurve(QtCore.QEasingCurve.InOutQuart) + self.animation.setEasingCurve(QtCore.QEasingCurve.Type.OutBounce) self.animation.start() def animateSwitch(self, index): @@ -313,10 +313,10 @@ class FaderWidget(QWidget): self.new_widget.setGraphicsEffect(self.effect) self.animation = QPropertyAnimation(self.effect, b"opacity") - self.animation.setDuration(300) + self.animation.setDuration(200) self.animation.setStartValue(0) self.animation.setEndValue(1) - self.animation.setEasingCurve(QEasingCurve.OutCubic) + self.animation.setEasingCurve(QEasingCurve.Type.InCubic) self.animation.finished.connect(self.close) self.animate() diff --git a/extras/VehicleSimulator.py b/extras/VehicleSimulator.py index cf790d2..da4bd9e 100644 --- a/extras/VehicleSimulator.py +++ b/extras/VehicleSimulator.py @@ -8,7 +8,7 @@ import math import random import time import threading -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from extras.KuksaClient import KuksaClient class VehicleSimulator(QObject): @@ -14,25 +14,21 @@ limitations under the License. """ -from Widgets.Dashboard import Dashboard -from extras.UI_Handeler import * import sys import os -from PyQt5 import uic, QtCore, QtWidgets -from PyQt5.QtWidgets import QApplication, QPushButton, QWidget +from PyQt6 import uic, QtCore, QtWidgets +from PyQt6.QtWidgets import QApplication, QPushButton, QWidget from functools import partial -from PyQt5 import QtGui -from PyQt5.QtCore import Qt -from PyQt5 import QtSvg -from PyQt5.QtSvg import * -from PyQt5.QtGui import QIcon - -import extras.config as config +from PyQt6 import QtGui +from PyQt6.QtCore import Qt current_dir = os.path.dirname(os.path.abspath(__file__)) Form, Base = uic.loadUiType(os.path.join(current_dir, "Main_Window.ui")) +from Widgets.Dashboard import Dashboard +from extras.UI_Handeler import * +import extras.config as config class MainWindow(Base, Form): """ @@ -53,8 +49,8 @@ class MainWindow(Base, Form): """ super(self.__class__, self).__init__(parent) self.setupUi(self) - self.setWindowFlags(QtCore.Qt.FramelessWindowHint) - self.setAttribute(QtCore.Qt.WA_TranslucentBackground) + self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint) + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground) self.setStyle(QtWidgets.QStyleFactory.create('Fusion')) # set fullscreen mode if enabled in config.ini @@ -104,10 +100,7 @@ class MainWindow(Base, Form): self.settingsBtn) steering_icon = ":/Images/Images/steering-wheel.svg" - svg_widget = QtSvg.QSvgWidget(steering_icon) - svg_widget.setFixedSize(QtSvg.QSvgRenderer(steering_icon).defaultSize()) - svg_widget.setStyleSheet("background-color: transparent;") - self.steeringCtrlButton.setIcon(QIcon(svg_widget.grab())) + self.steeringCtrlButton.setIcon(QtGui.QIcon(steering_icon)) if not config.hvac_enabled(): self.hvacButton.hide() @@ -150,7 +143,7 @@ class MainWindow(Base, Form): } """) self.centralwidget.layout().addWidget( - self.size_grip, 0, Qt.AlignBottom | Qt.AlignRight) + self.size_grip, 0, Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignRight) def VSS_callback(self, data): pass @@ -188,4 +181,4 @@ if __name__ == '__main__': ':/Images/Images/Automotive_Grade_Linux_logo.svg')) window = MainWindow() window.show() - sys.exit(app.exec_()) + sys.exit(app.exec()) diff --git a/requirements.txt b/requirements.txt index 4b98567..490e913 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ -pyqt5==5.15 +PyQt6==6.7.0 +PyQt6-Qt6==6.7.1 +PyQt6-sip==13.6.0 +PySide6==6.7.1 +PySide6_Addons==6.7.1 +PySide6_Essentials==6.7.1 kuksa-client==0.4.0 -python-can>=4.2.2 -qtpy==2.3.1 -qtwidgets==1.1
\ No newline at end of file +python-can>=4.2.2
\ No newline at end of file |