mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-04-22 00:04:35 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 162e0ae78b | |||
| 99d5e8e71c | |||
| 6c1f89ad39 | |||
| 7fb938a850 | |||
| 08c3d7d175 | |||
| af23e74f71 | |||
| 0bf1cf9b8a |
+22
-26
@@ -1,5 +1,27 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.100.0 (2024-09-01)
|
||||
|
||||
### Documentation
|
||||
|
||||
* docs(becwidget): improvements to the bec widget base class docs; fixed type hint import for sphinx ([`99d5e8e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/99d5e8e71c7f89a53d7967126f4056dde005534c))
|
||||
|
||||
### Feature
|
||||
|
||||
* feat(theme): added theme handler to bec widget base class; added tests ([`7fb938a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7fb938a8506685278ee5eeb6fe9a03f74b713cf8))
|
||||
|
||||
### Fix
|
||||
|
||||
* fix(pyqt slot): removed slot decorator to avoid problems with pyqt6 ([`6c1f89a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6c1f89ad39b7240ab1d1c1123422b99ae195bf01))
|
||||
|
||||
## v0.99.15 (2024-08-31)
|
||||
|
||||
### Fix
|
||||
|
||||
* fix(theme): update pg axes on theme update ([`af23e74`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/af23e74f71152f4abc319ab7b45e65deefde3519))
|
||||
|
||||
* fix(positioner_box): fixed positioner box dialog; added test; closes #332 ([`0bf1cf9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0bf1cf9b8ab2f9171d5ff63d4e3672eb93e9a5fa))
|
||||
|
||||
## v0.99.14 (2024-08-30)
|
||||
|
||||
### Fix
|
||||
@@ -129,29 +151,3 @@
|
||||
* fix(color maps): color maps should take the background color into account; fixed min colors to 10 ([`060935f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/060935ffc5472a958c337bf60834c5291f104ece))
|
||||
|
||||
## v0.99.2 (2024-08-27)
|
||||
|
||||
### Ci
|
||||
|
||||
* ci: additional tests are not allowed to fail ([`bb385f0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bb385f07ca18904461a541b5cadde05398c84438))
|
||||
|
||||
### Fix
|
||||
|
||||
* fix(widgets): fixed default theme for widgets
|
||||
|
||||
If not theme is set, the init of the BECWidget base class sets the default theme to "dark" ([`cf28730`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/cf28730515e3c2d5914e0205768734c578711e5c))
|
||||
|
||||
## v0.99.1 (2024-08-27)
|
||||
|
||||
### Fix
|
||||
|
||||
* fix(crosshair): emit all crosshair events, not just line coordinates ([`2265458`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2265458dcc57970db18c62619f5877d542d72e81))
|
||||
|
||||
## v0.99.0 (2024-08-25)
|
||||
|
||||
### Documentation
|
||||
|
||||
* docs(darkmodebutton): added dark mode button docs ([`406c263`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/406c263746f0e809c1a4d98356c48f40428c23d7))
|
||||
|
||||
### Refactor
|
||||
|
||||
* refactor(darkmodebutton): renamed set_dark_mode_enabled to toggle_dark_mode ([`c70724a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c70724a456900bcb06b040407a2c5d497e49ce77))
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# pylint: disable=no-name-in-module
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import defaultdict
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from qtpy.QtCore import Slot
|
||||
from qtpy.QtWidgets import QApplication, QWidget
|
||||
|
||||
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
|
||||
@@ -11,7 +14,30 @@ class BECWidget(BECConnector):
|
||||
# from fonts.google.com/icons. Override this in subclasses to set the icon name.
|
||||
ICON_NAME = "widgets"
|
||||
|
||||
def __init__(self, client=None, config: ConnectionConfig = None, gui_id: str = None):
|
||||
def __init__(
|
||||
self,
|
||||
client=None,
|
||||
config: ConnectionConfig = None,
|
||||
gui_id: str = None,
|
||||
theme_update: bool = False,
|
||||
):
|
||||
"""
|
||||
Base class for all BEC widgets. This class should be used as a mixin class for all BEC widgets, e.g.:
|
||||
|
||||
|
||||
>>> class MyWidget(BECWidget, QWidget):
|
||||
>>> def __init__(self, parent=None, client=None, config=None, gui_id=None):
|
||||
>>> super().__init__(client=client, config=config, gui_id=gui_id)
|
||||
>>> QWidget.__init__(self, parent=parent)
|
||||
|
||||
|
||||
Args:
|
||||
client(BECClient, optional): The BEC client.
|
||||
config(ConnectionConfig, optional): The connection configuration.
|
||||
gui_id(str, optional): The GUI ID.
|
||||
theme_update(bool, optional): Whether to subscribe to theme updates. Defaults to False. When set to True, the
|
||||
widget's apply_theme method will be called when the theme changes.
|
||||
"""
|
||||
if not isinstance(self, QWidget):
|
||||
raise RuntimeError(f"{repr(self)} is not a subclass of QWidget")
|
||||
super().__init__(client, config, gui_id)
|
||||
@@ -19,7 +45,35 @@ class BECWidget(BECConnector):
|
||||
# Set the theme to auto if it is not set yet
|
||||
app = QApplication.instance()
|
||||
if not hasattr(app, "theme"):
|
||||
set_theme("dark")
|
||||
set_theme("auto")
|
||||
|
||||
if theme_update:
|
||||
self._connect_to_theme_change()
|
||||
|
||||
def _connect_to_theme_change(self):
|
||||
"""Connect to the theme change signal."""
|
||||
qapp = QApplication.instance()
|
||||
if hasattr(qapp, "theme_signal"):
|
||||
qapp.theme_signal.theme_updated.connect(self._update_theme)
|
||||
|
||||
def _update_theme(self, theme: str):
|
||||
"""Update the theme."""
|
||||
if theme is None:
|
||||
qapp = QApplication.instance()
|
||||
if hasattr(qapp, "theme"):
|
||||
theme = qapp.theme["theme"]
|
||||
else:
|
||||
theme = "dark"
|
||||
self.apply_theme(theme)
|
||||
|
||||
@Slot(str)
|
||||
def apply_theme(self, theme: str):
|
||||
"""
|
||||
Apply the theme to the widget.
|
||||
|
||||
Args:
|
||||
theme(str, optional): The theme to be applied.
|
||||
"""
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup the widget."""
|
||||
|
||||
+20
-21
@@ -19,6 +19,17 @@ def get_theme_palette():
|
||||
return bec_qthemes.load_palette(theme)
|
||||
|
||||
|
||||
def _theme_update_callback():
|
||||
"""
|
||||
Internal callback function to update the theme based on the system theme.
|
||||
"""
|
||||
app = QApplication.instance()
|
||||
# pylint: disable=protected-access
|
||||
app.theme["theme"] = app.os_listener._theme.lower()
|
||||
app.theme_signal.theme_updated.emit(app.theme["theme"])
|
||||
apply_theme(app.os_listener._theme.lower())
|
||||
|
||||
|
||||
def set_theme(theme: Literal["dark", "light", "auto"]):
|
||||
"""
|
||||
Set the theme for the application.
|
||||
@@ -27,21 +38,17 @@ def set_theme(theme: Literal["dark", "light", "auto"]):
|
||||
theme (Literal["dark", "light", "auto"]): The theme to set. "auto" will automatically switch between dark and light themes based on the system theme.
|
||||
"""
|
||||
app = QApplication.instance()
|
||||
bec_qthemes.setup_theme(theme)
|
||||
pg.setConfigOption("background", "w" if app.theme["theme"] == "light" else "k")
|
||||
bec_qthemes.setup_theme(theme, install_event_filter=False)
|
||||
|
||||
app.theme_signal.theme_updated.emit(theme)
|
||||
apply_theme(theme)
|
||||
|
||||
# pylint: disable=protected-access
|
||||
if theme != "auto":
|
||||
return
|
||||
|
||||
def callback():
|
||||
app.theme["theme"] = listener._theme.lower()
|
||||
apply_theme(listener._theme.lower())
|
||||
|
||||
listener = OSThemeSwitchListener(callback)
|
||||
|
||||
app.installEventFilter(listener)
|
||||
if not hasattr(app, "os_listener") or app.os_listener is None:
|
||||
app.os_listener = OSThemeSwitchListener(_theme_update_callback)
|
||||
app.installEventFilter(app.os_listener)
|
||||
|
||||
|
||||
def apply_theme(theme: Literal["dark", "light"]):
|
||||
@@ -53,20 +60,12 @@ def apply_theme(theme: Literal["dark", "light"]):
|
||||
children = itertools.chain.from_iterable(
|
||||
top.findChildren(pg.GraphicsLayoutWidget) for top in app.topLevelWidgets()
|
||||
)
|
||||
pg.setConfigOptions(
|
||||
foreground="d" if theme == "dark" else "k", background="k" if theme == "dark" else "w"
|
||||
)
|
||||
for pg_widget in children:
|
||||
pg_widget.setBackground("k" if theme == "dark" else "w")
|
||||
|
||||
dark_mode_buttons = [
|
||||
button
|
||||
for button in app.topLevelWidgets()
|
||||
if hasattr(button, "dark_mode_enabled")
|
||||
and hasattr(button, "mode_button")
|
||||
and isinstance(button.mode_button, (QPushButton, QToolButton))
|
||||
]
|
||||
|
||||
for button in dark_mode_buttons:
|
||||
button.dark_mode_enabled = theme == "dark"
|
||||
button.update_mode_button()
|
||||
# now define stylesheet according to theme and apply it
|
||||
style = bec_qthemes.load_stylesheet(theme)
|
||||
app.setStyleSheet(style)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from bec_qthemes import material_icon
|
||||
from qtpy.QtCore import Property, Qt, Slot
|
||||
from qtpy.QtWidgets import QApplication, QHBoxLayout, QPushButton, QToolButton, QWidget
|
||||
@@ -18,7 +20,7 @@ class DarkModeButton(BECWidget, QWidget):
|
||||
gui_id: str | None = None,
|
||||
toolbar: bool = False,
|
||||
) -> None:
|
||||
super().__init__(client=client, gui_id=gui_id)
|
||||
super().__init__(client=client, gui_id=gui_id, theme_update=True)
|
||||
QWidget.__init__(self, parent)
|
||||
|
||||
self._dark_mode_enabled = False
|
||||
@@ -39,6 +41,17 @@ class DarkModeButton(BECWidget, QWidget):
|
||||
self.setLayout(self.layout)
|
||||
self.setFixedSize(40, 40)
|
||||
|
||||
@Slot(str)
|
||||
def apply_theme(self, theme: str):
|
||||
"""
|
||||
Apply the theme to the widget.
|
||||
|
||||
Args:
|
||||
theme(str, optional): The theme to be applied.
|
||||
"""
|
||||
self.dark_mode_enabled = theme == "dark"
|
||||
self.update_mode_button()
|
||||
|
||||
def _get_qapp_dark_mode_state(self) -> bool:
|
||||
"""
|
||||
Get the dark mode state from the QApplication.
|
||||
|
||||
@@ -2,10 +2,11 @@ from __future__ import annotations
|
||||
|
||||
from typing import Literal, Optional
|
||||
|
||||
import bec_qthemes
|
||||
import pyqtgraph as pg
|
||||
from pydantic import BaseModel, Field
|
||||
from qtpy.QtCore import Signal, Slot
|
||||
from qtpy.QtWidgets import QWidget
|
||||
from qtpy.QtWidgets import QApplication, QWidget
|
||||
|
||||
from bec_widgets.utils import BECConnector, ConnectionConfig
|
||||
from bec_widgets.utils.crosshair import Crosshair
|
||||
@@ -98,6 +99,38 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
|
||||
|
||||
self.add_legend()
|
||||
self.crosshair = None
|
||||
self._connect_to_theme_change()
|
||||
|
||||
def _connect_to_theme_change(self):
|
||||
"""Connect to the theme change signal."""
|
||||
qapp = QApplication.instance()
|
||||
if hasattr(qapp, "theme_signal"):
|
||||
qapp.theme_signal.theme_updated.connect(self._update_theme)
|
||||
|
||||
@Slot(str)
|
||||
def _update_theme(self, theme: str):
|
||||
"""Update the theme."""
|
||||
if theme is None:
|
||||
qapp = QApplication.instance()
|
||||
if hasattr(qapp, "theme"):
|
||||
theme = qapp.theme["theme"]
|
||||
else:
|
||||
theme = "dark"
|
||||
self.apply_theme(theme)
|
||||
|
||||
def apply_theme(self, theme: str):
|
||||
"""
|
||||
Apply the theme to the plot widget.
|
||||
|
||||
Args:
|
||||
theme(str, optional): The theme to be applied.
|
||||
"""
|
||||
palette = bec_qthemes.load_palette(theme)
|
||||
text_pen = pg.mkPen(color=palette.text().color())
|
||||
|
||||
for axis in ["left", "bottom", "right", "top"]:
|
||||
self.plot_item.getAxis(axis).setPen(text_pen)
|
||||
self.plot_item.getAxis(axis).setTextPen(text_pen)
|
||||
|
||||
def set(self, **kwargs) -> None:
|
||||
"""
|
||||
|
||||
@@ -46,6 +46,7 @@ class PositionerBox(BECWidget, QWidget):
|
||||
self.get_bec_shortcuts()
|
||||
self._device = ""
|
||||
self._limits = None
|
||||
self._dialog = None
|
||||
|
||||
self.init_ui()
|
||||
|
||||
@@ -87,17 +88,18 @@ class PositionerBox(BECWidget, QWidget):
|
||||
|
||||
def _open_dialog_selection(self):
|
||||
"""Open dialog window for positioner selection"""
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("Positioner Selection")
|
||||
self._dialog = QDialog(self)
|
||||
self._dialog.setWindowTitle("Positioner Selection")
|
||||
layout = QVBoxLayout()
|
||||
line_edit = DeviceLineEdit(self, client=self.client, device_filter="Positioner")
|
||||
line_edit.textChanged.connect(self._positioner_changed)
|
||||
line_edit.textChanged.connect(self.set_positioner)
|
||||
layout.addWidget(line_edit)
|
||||
close_button = QPushButton("Close")
|
||||
close_button.clicked.connect(dialog.accept)
|
||||
close_button.clicked.connect(self._dialog.accept)
|
||||
layout.addWidget(close_button)
|
||||
dialog.setLayout(layout)
|
||||
dialog.exec()
|
||||
self._dialog.setLayout(layout)
|
||||
self._dialog.exec()
|
||||
self._dialog = None
|
||||
|
||||
def init_device(self):
|
||||
"""Init the device view and readback"""
|
||||
|
||||
@@ -39,6 +39,10 @@ integrated with the BEC system by providing:
|
||||
from the `BECIPythonClient` via CLI, providing powerful control and automation capabilities. For example, you can
|
||||
remotely adjust widget settings, start/stop operations, or query the widget’s status directly from the command line.
|
||||
|
||||
5. **Reacting to Theme Changes**: The base class provides a dedicated input flag to subscribe to theme changes, allowing
|
||||
your widget to adapt its appearance based on the current theme (e.g., light or dark mode) and can even synchronize with the user's OS settings. The widget-specific logic can then
|
||||
be implemented in the `apply_theme` method, which is called whenever the theme changes. This ensures a consistent user experience across different themes and environments.
|
||||
|
||||
Here’s a basic example of a widget inheriting
|
||||
from [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget):
|
||||
|
||||
@@ -46,10 +50,9 @@ from [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from qtpy.QtWidgets import QWidget, QVBoxLayout
|
||||
|
||||
|
||||
class MyWidget(BECWidget, QWidget):
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs) # disable theme updates
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.get_bec_shortcuts() # Initialize BEC shortcuts
|
||||
self.init_ui()
|
||||
@@ -58,6 +61,26 @@ class MyWidget(BECWidget, QWidget):
|
||||
layout = QVBoxLayout(self)
|
||||
# Add more UI components here
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
# To enable theme updates, set theme_update=True, e.g.:
|
||||
|
||||
class MyDynamicWidget(BECWidget, QWidget):
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
super().__init__(*args, theme_update=True, **kwargs) # enable theme updates
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.get_bec_shortcuts() # Initialize BEC shortcuts
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
# Add more UI components here
|
||||
self.setLayout(layout)
|
||||
|
||||
def apply_theme(self, theme):
|
||||
# Implement theme-specific logic here
|
||||
pass
|
||||
|
||||
```
|
||||
|
||||
### The Role of `BECConnector`
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "bec_widgets"
|
||||
version = "0.99.14"
|
||||
version = "0.100.0"
|
||||
description = "BEC Widgets"
|
||||
requires-python = ">=3.10"
|
||||
classifiers = [
|
||||
|
||||
@@ -14,6 +14,8 @@ def qapplication(qtbot): # pylint: disable=unused-argument
|
||||
qapp = QApplication.instance()
|
||||
# qapp.quit()
|
||||
qapp.processEvents()
|
||||
if hasattr(qapp, "os_listener") and qapp.os_listener:
|
||||
qapp.removeEventFilter(qapp.os_listener)
|
||||
try:
|
||||
qtbot.waitUntil(lambda: qapp.topLevelWidgets() == [])
|
||||
except QtBotTimeoutError as exc:
|
||||
|
||||
@@ -2,6 +2,7 @@ from unittest import mock
|
||||
|
||||
import pytest
|
||||
from qtpy.QtCore import Qt
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
from bec_widgets.utils.colors import set_theme
|
||||
from bec_widgets.widgets.dark_mode_button.dark_mode_button import DarkModeButton
|
||||
@@ -70,3 +71,16 @@ def test_dark_mode_button_changes_theme(dark_mode_button):
|
||||
|
||||
dark_mode_button.toggle_dark_mode()
|
||||
mocked_set_theme.assert_called_with("light")
|
||||
|
||||
|
||||
def test_dark_mode_button_changes_on_os_theme_change(qtbot, dark_mode_button):
|
||||
"""
|
||||
Test that the dark mode button changes the theme correctly when the OS theme changes.
|
||||
"""
|
||||
qapp = QApplication.instance()
|
||||
assert dark_mode_button.dark_mode_enabled is False
|
||||
assert dark_mode_button.mode_button.toolTip() == "Set Dark Mode"
|
||||
qapp.theme_signal.theme_updated.emit("dark")
|
||||
qtbot.wait(100)
|
||||
assert dark_mode_button.dark_mode_enabled is True
|
||||
assert dark_mode_button.mode_button.toolTip() == "Set Light Mode"
|
||||
|
||||
@@ -4,8 +4,11 @@ import pytest
|
||||
from bec_lib.device import Positioner
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
from bec_lib.messages import ScanQueueMessage
|
||||
from qtpy.QtCore import Qt, QTimer
|
||||
from qtpy.QtGui import QValidator
|
||||
from qtpy.QtWidgets import QPushButton
|
||||
|
||||
from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
|
||||
from bec_widgets.widgets.positioner_box.positioner_box import PositionerBox
|
||||
from bec_widgets.widgets.positioner_box.positioner_control_line import PositionerControlLine
|
||||
|
||||
@@ -128,3 +131,23 @@ def test_positioner_control_line(qtbot, mocked_client):
|
||||
|
||||
assert db.ui.device_box.height() == 60
|
||||
assert db.ui.device_box.width() == 600
|
||||
|
||||
|
||||
def test_positioner_box_open_dialog_selection(qtbot, positioner_box):
|
||||
"""Test open positioner edit"""
|
||||
|
||||
# Use a timer to close the dialog after it opens
|
||||
def close_dialog():
|
||||
# pylint: disable=protected-access
|
||||
assert positioner_box._dialog is not None
|
||||
qtbot.waitUntil(lambda: positioner_box._dialog.isVisible() is True, timeout=1000)
|
||||
line_edit = positioner_box._dialog.findChild(DeviceLineEdit)
|
||||
line_edit.setText("samy")
|
||||
close_button = positioner_box._dialog.findChild(QPushButton)
|
||||
assert close_button.text() == "Close"
|
||||
qtbot.mouseClick(close_button, Qt.LeftButton)
|
||||
|
||||
# Execute the timer after the dialog opens to close it
|
||||
QTimer.singleShot(100, close_dialog)
|
||||
qtbot.mouseClick(positioner_box.ui.tool_button, Qt.LeftButton)
|
||||
assert positioner_box.device == "samy"
|
||||
|
||||
@@ -61,7 +61,7 @@ def test_vscode_cleanup(qtbot, patched_vscode_process):
|
||||
vscode_patched, mock_killpg = patched_vscode_process
|
||||
vscode_patched.process.pid = 123
|
||||
vscode_patched.process.poll.return_value = None
|
||||
vscode_patched.cleanup()
|
||||
vscode_patched.cleanup_vscode()
|
||||
mock_killpg.assert_called_once_with(123, 15)
|
||||
vscode_patched.process.wait.assert_called_once()
|
||||
|
||||
@@ -70,6 +70,6 @@ def test_close_event_on_terminated_code(qtbot, patched_vscode_process):
|
||||
vscode_patched, mock_killpg = patched_vscode_process
|
||||
vscode_patched.process.pid = 123
|
||||
vscode_patched.process.poll.return_value = 0
|
||||
vscode_patched.cleanup()
|
||||
vscode_patched.cleanup_vscode()
|
||||
mock_killpg.assert_not_called()
|
||||
vscode_patched.process.wait.assert_not_called()
|
||||
|
||||
@@ -2,8 +2,11 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pyqtgraph as pg
|
||||
import pytest
|
||||
from qtpy.QtGui import QColor
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
from bec_widgets.qt_utils.settings_dialog import SettingsDialog
|
||||
from bec_widgets.utils.colors import apply_theme, get_theme_palette, set_theme
|
||||
from bec_widgets.widgets.figure.plots.axis_settings import AxisSettings
|
||||
from bec_widgets.widgets.waveform.waveform_popups.curve_dialog.curve_dialog import CurveSettings
|
||||
from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget
|
||||
@@ -460,3 +463,42 @@ def test_axis_dialog_set_properties(qtbot, waveform_widget):
|
||||
assert waveform_widget._config_dict["axis"]["y_scale"] == "linear"
|
||||
assert waveform_widget._config_dict["axis"]["x_lim"] == (5, 15)
|
||||
assert waveform_widget._config_dict["axis"]["y_lim"] == (5, 15)
|
||||
|
||||
|
||||
def test_waveform_widget_theme_update(qtbot, waveform_widget):
|
||||
"""Test theme update for waveform widget."""
|
||||
qapp = QApplication.instance()
|
||||
|
||||
# Set the theme directly; equivalent to clicking the dark mode button
|
||||
# The background color should be black and the axis color should be white
|
||||
set_theme("dark")
|
||||
palette = get_theme_palette()
|
||||
waveform_color_dark = waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = waveform_widget.fig.backgroundBrush().color()
|
||||
assert bg_color == QColor("black")
|
||||
assert waveform_color_dark == palette.text().color()
|
||||
|
||||
# Set the theme to light; equivalent to clicking the light mode button
|
||||
# The background color should be white and the axis color should be black
|
||||
set_theme("light")
|
||||
palette = get_theme_palette()
|
||||
waveform_color_light = waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = waveform_widget.fig.backgroundBrush().color()
|
||||
assert bg_color == QColor("white")
|
||||
assert waveform_color_light == palette.text().color()
|
||||
|
||||
assert waveform_color_dark != waveform_color_light
|
||||
|
||||
# Set the theme to auto; equivalent starting the application with no theme set
|
||||
set_theme("auto")
|
||||
# Simulate that the OS theme changes to dark
|
||||
qapp.theme_signal.theme_updated.emit("dark")
|
||||
apply_theme("dark")
|
||||
|
||||
# The background color should be black and the axis color should be white
|
||||
# As we don't have access to the listener here, we can't test the palette change. Instead,
|
||||
# we compare the waveform color to the dark theme color
|
||||
waveform_color = waveform_widget.waveform.plot_item.getAxis("left").pen().color()
|
||||
bg_color = waveform_widget.fig.backgroundBrush().color()
|
||||
assert bg_color == QColor("black")
|
||||
assert waveform_color == waveform_color_dark
|
||||
|
||||
Reference in New Issue
Block a user