-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into lint
- Loading branch information
Showing
7 changed files
with
160 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,45 @@ | ||
class Style: | ||
"""Represents a single class that can be applied to gui objects to change their appearance.""" | ||
from PyQt6.QtWidgets import QWidget, QPushButton | ||
|
||
PROPERTY_NAME: str | ||
|
||
class IndicatorMixin(QWidget): | ||
|
||
class WidgetState(Style): | ||
"""Represents the state of a widget that can be alternately active or inactive.""" | ||
|
||
PROPERTY_NAME = "widgetState" | ||
_PROPERTY_NAME = "widgetState" | ||
|
||
# A component is running, enabled, or armed | ||
ON = "on" | ||
_ON = "on" | ||
|
||
# A component is disabled, not running, or disarmed, but could be enabled through this widget | ||
OFF = "off" | ||
_OFF = "off" | ||
|
||
# A component is disabled, not expected to have any effect or perform its function because of | ||
# some external factor, either another widget or something external to the gui | ||
# For example, a the arm button when the pi is not connected | ||
INACTIVE = "inactive" | ||
_INACTIVE = "inactive" | ||
|
||
# Removes any state | ||
_NO_STATE = "" | ||
|
||
def set_on(self) -> None: | ||
self.setProperty(IndicatorMixin._PROPERTY_NAME, IndicatorMixin._ON) | ||
self._update_style() | ||
|
||
def set_off(self) -> None: | ||
self.setProperty(IndicatorMixin._PROPERTY_NAME, IndicatorMixin._OFF) | ||
self._update_style() | ||
|
||
def set_inactive(self) -> None: | ||
self.setProperty(IndicatorMixin._PROPERTY_NAME, IndicatorMixin._INACTIVE) | ||
self._update_style() | ||
|
||
def remove_state(self) -> None: | ||
self.setProperty(IndicatorMixin._PROPERTY_NAME, IndicatorMixin._NO_STATE) | ||
self._update_style() | ||
|
||
def _update_style(self) -> None: | ||
style = self.style() | ||
if style is not None: | ||
style.polish(self) | ||
|
||
|
||
class ButtonIndicator(QPushButton, IndicatorMixin): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from typing import Optional | ||
from gui.styles.custom_styles import IndicatorMixin | ||
from PyQt6.QtCore import QSize, Qt | ||
from PyQt6.QtGui import QColor | ||
from PyQt6.QtWidgets import QWidget, QLabel | ||
|
||
|
||
class Circle(QLabel): | ||
def __init__(self, parent: Optional[QWidget] = None, | ||
radius: int = 50, | ||
color: Optional[QColor | Qt.GlobalColor] = None) -> None: | ||
super().__init__(parent) | ||
self.setFixedSize(QSize(2 * radius, 2 * radius)) | ||
stylesheet = self.styleSheet() | ||
self.setStyleSheet(f"{stylesheet}border-radius: {radius}px;") | ||
|
||
if color: | ||
self.set_color(color) | ||
|
||
def set_color(self, color: QColor | Qt.GlobalColor) -> None: | ||
if isinstance(color, Qt.GlobalColor): | ||
color = QColor(color) | ||
style = f"background-color: rgb({color.red()}, {color.green()}, {color.blue()});" | ||
self.setStyleSheet(f"{self.styleSheet()}{style}") | ||
|
||
|
||
class CircleIndicator(Circle, IndicatorMixin): | ||
def __init__(self, parent: Optional[QWidget] = None, | ||
radius: int = 50) -> None: | ||
super().__init__(parent, radius) | ||
self.set_inactive() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from gui.event_nodes.subscriber import GUIEventSubscriber | ||
from gui.widgets.circle import CircleIndicator | ||
from PyQt6.QtCore import pyqtSignal, pyqtSlot | ||
from PyQt6.QtGui import QFont | ||
from PyQt6.QtWidgets import QHBoxLayout, QLabel, QVBoxLayout, QWidget | ||
|
||
from rov_msgs.msg import VehicleState | ||
|
||
|
||
class HeartbeatWidget(QWidget): | ||
|
||
signal = pyqtSignal(VehicleState) | ||
|
||
def __init__(self) -> None: | ||
super().__init__() | ||
|
||
self.signal.connect(self.refresh) | ||
self.subscription = GUIEventSubscriber(VehicleState, 'vehicle_state_event', self.signal) | ||
# Create a latch variable | ||
self.warning_msg_latch: bool = False | ||
|
||
heartbeat_layout = QVBoxLayout() | ||
|
||
font = QFont("Arial", 14) | ||
|
||
pi_status_layout = QHBoxLayout() | ||
self.pi_indicator = QLabel('No Pi Status') | ||
self.pi_indicator.setFont(font) | ||
pi_status_layout.addWidget(self.pi_indicator) | ||
self.pi_indicator_circle = CircleIndicator(radius=10) | ||
pi_status_layout.addWidget(self.pi_indicator_circle) | ||
heartbeat_layout.addLayout(pi_status_layout) | ||
|
||
pixhawk_status_layout = QHBoxLayout() | ||
self.pixhawk_indicator = QLabel('No Pixhawk Status') | ||
self.pixhawk_indicator.setFont(font) | ||
pixhawk_status_layout.addWidget(self.pixhawk_indicator) | ||
self.pixhawk_indicator_circle = CircleIndicator(radius=10) | ||
pixhawk_status_layout.addWidget(self.pixhawk_indicator_circle) | ||
heartbeat_layout.addLayout(pixhawk_status_layout) | ||
|
||
self.setLayout(heartbeat_layout) | ||
|
||
@pyqtSlot(VehicleState) | ||
def refresh(self, msg: VehicleState) -> None: | ||
if msg.pi_connected: | ||
self.pi_indicator.setText('Pi Connected') | ||
self.pi_indicator_circle.set_on() | ||
else: | ||
self.pi_indicator.setText('Pi Disconnected') | ||
self.pi_indicator_circle.set_off() | ||
|
||
if msg.pixhawk_connected: | ||
self.pixhawk_indicator.setText('Pixhawk Connected') | ||
self.pixhawk_indicator_circle.set_on() | ||
else: | ||
self.pixhawk_indicator.setText('Pixhawk Disconnected') | ||
self.pixhawk_indicator_circle.set_off() |