bec-widgets 0.99.15__py3-none-any.whl → 0.100.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.100.0 (2024-09-01)
4
+
5
+ ### Documentation
6
+
7
+ * 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))
8
+
9
+ ### Feature
10
+
11
+ * feat(theme): added theme handler to bec widget base class; added tests ([`7fb938a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7fb938a8506685278ee5eeb6fe9a03f74b713cf8))
12
+
13
+ ### Fix
14
+
15
+ * fix(pyqt slot): removed slot decorator to avoid problems with pyqt6 ([`6c1f89a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6c1f89ad39b7240ab1d1c1123422b99ae195bf01))
16
+
3
17
  ## v0.99.15 (2024-08-31)
4
18
 
5
19
  ### Fix
@@ -137,21 +151,3 @@
137
151
  * 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))
138
152
 
139
153
  ## v0.99.2 (2024-08-27)
140
-
141
- ### Ci
142
-
143
- * ci: additional tests are not allowed to fail ([`bb385f0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bb385f07ca18904461a541b5cadde05398c84438))
144
-
145
- ### Fix
146
-
147
- * fix(widgets): fixed default theme for widgets
148
-
149
- 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))
150
-
151
- ## v0.99.1 (2024-08-27)
152
-
153
- ### Fix
154
-
155
- * fix(crosshair): emit all crosshair events, not just line coordinates ([`2265458`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2265458dcc57970db18c62619f5877d542d72e81))
156
-
157
- ## v0.99.0 (2024-08-25)
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.99.15
3
+ Version: 0.100.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -1,4 +1,6 @@
1
1
  # pylint: disable=no-name-in-module
2
+ from __future__ import annotations
3
+
2
4
  import os
3
5
  from abc import ABC, abstractmethod
4
6
  from collections import defaultdict
@@ -1,3 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ from qtpy.QtCore import Slot
1
4
  from qtpy.QtWidgets import QApplication, QWidget
2
5
 
3
6
  from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
@@ -11,7 +14,30 @@ class BECWidget(BECConnector):
11
14
  # from fonts.google.com/icons. Override this in subclasses to set the icon name.
12
15
  ICON_NAME = "widgets"
13
16
 
14
- def __init__(self, client=None, config: ConnectionConfig = None, gui_id: str = None):
17
+ def __init__(
18
+ self,
19
+ client=None,
20
+ config: ConnectionConfig = None,
21
+ gui_id: str = None,
22
+ theme_update: bool = False,
23
+ ):
24
+ """
25
+ Base class for all BEC widgets. This class should be used as a mixin class for all BEC widgets, e.g.:
26
+
27
+
28
+ >>> class MyWidget(BECWidget, QWidget):
29
+ >>> def __init__(self, parent=None, client=None, config=None, gui_id=None):
30
+ >>> super().__init__(client=client, config=config, gui_id=gui_id)
31
+ >>> QWidget.__init__(self, parent=parent)
32
+
33
+
34
+ Args:
35
+ client(BECClient, optional): The BEC client.
36
+ config(ConnectionConfig, optional): The connection configuration.
37
+ gui_id(str, optional): The GUI ID.
38
+ theme_update(bool, optional): Whether to subscribe to theme updates. Defaults to False. When set to True, the
39
+ widget's apply_theme method will be called when the theme changes.
40
+ """
15
41
  if not isinstance(self, QWidget):
16
42
  raise RuntimeError(f"{repr(self)} is not a subclass of QWidget")
17
43
  super().__init__(client, config, gui_id)
@@ -19,7 +45,35 @@ class BECWidget(BECConnector):
19
45
  # Set the theme to auto if it is not set yet
20
46
  app = QApplication.instance()
21
47
  if not hasattr(app, "theme"):
22
- set_theme("dark")
48
+ set_theme("auto")
49
+
50
+ if theme_update:
51
+ self._connect_to_theme_change()
52
+
53
+ def _connect_to_theme_change(self):
54
+ """Connect to the theme change signal."""
55
+ qapp = QApplication.instance()
56
+ if hasattr(qapp, "theme_signal"):
57
+ qapp.theme_signal.theme_updated.connect(self._update_theme)
58
+
59
+ def _update_theme(self, theme: str):
60
+ """Update the theme."""
61
+ if theme is None:
62
+ qapp = QApplication.instance()
63
+ if hasattr(qapp, "theme"):
64
+ theme = qapp.theme["theme"]
65
+ else:
66
+ theme = "dark"
67
+ self.apply_theme(theme)
68
+
69
+ @Slot(str)
70
+ def apply_theme(self, theme: str):
71
+ """
72
+ Apply the theme to the widget.
73
+
74
+ Args:
75
+ theme(str, optional): The theme to be applied.
76
+ """
23
77
 
24
78
  def cleanup(self):
25
79
  """Cleanup the widget."""
@@ -19,6 +19,17 @@ def get_theme_palette():
19
19
  return bec_qthemes.load_palette(theme)
20
20
 
21
21
 
22
+ def _theme_update_callback():
23
+ """
24
+ Internal callback function to update the theme based on the system theme.
25
+ """
26
+ app = QApplication.instance()
27
+ # pylint: disable=protected-access
28
+ app.theme["theme"] = app.os_listener._theme.lower()
29
+ app.theme_signal.theme_updated.emit(app.theme["theme"])
30
+ apply_theme(app.os_listener._theme.lower())
31
+
32
+
22
33
  def set_theme(theme: Literal["dark", "light", "auto"]):
23
34
  """
24
35
  Set the theme for the application.
@@ -27,23 +38,17 @@ def set_theme(theme: Literal["dark", "light", "auto"]):
27
38
  theme (Literal["dark", "light", "auto"]): The theme to set. "auto" will automatically switch between dark and light themes based on the system theme.
28
39
  """
29
40
  app = QApplication.instance()
30
- bec_qthemes.setup_theme(theme)
31
- pg.setConfigOption("background", "w" if app.theme["theme"] == "light" else "k")
41
+ bec_qthemes.setup_theme(theme, install_event_filter=False)
42
+
32
43
  app.theme_signal.theme_updated.emit(theme)
33
44
  apply_theme(theme)
34
45
 
35
- # pylint: disable=protected-access
36
46
  if theme != "auto":
37
47
  return
38
48
 
39
- def callback():
40
- app.theme["theme"] = listener._theme.lower()
41
- app.theme_signal.theme_updated.emit(app.theme["theme"])
42
- apply_theme(listener._theme.lower())
43
-
44
- listener = OSThemeSwitchListener(callback)
45
-
46
- app.installEventFilter(listener)
49
+ if not hasattr(app, "os_listener") or app.os_listener is None:
50
+ app.os_listener = OSThemeSwitchListener(_theme_update_callback)
51
+ app.installEventFilter(app.os_listener)
47
52
 
48
53
 
49
54
  def apply_theme(theme: Literal["dark", "light"]):
@@ -55,21 +60,12 @@ def apply_theme(theme: Literal["dark", "light"]):
55
60
  children = itertools.chain.from_iterable(
56
61
  top.findChildren(pg.GraphicsLayoutWidget) for top in app.topLevelWidgets()
57
62
  )
58
- pg.setConfigOptions(foreground="d" if theme == "dark" else "k")
63
+ pg.setConfigOptions(
64
+ foreground="d" if theme == "dark" else "k", background="k" if theme == "dark" else "w"
65
+ )
59
66
  for pg_widget in children:
60
67
  pg_widget.setBackground("k" if theme == "dark" else "w")
61
68
 
62
- dark_mode_buttons = [
63
- button
64
- for button in app.topLevelWidgets()
65
- if hasattr(button, "dark_mode_enabled")
66
- and hasattr(button, "mode_button")
67
- and isinstance(button.mode_button, (QPushButton, QToolButton))
68
- ]
69
-
70
- for button in dark_mode_buttons:
71
- button.dark_mode_enabled = theme == "dark"
72
- button.update_mode_button()
73
69
  # now define stylesheet according to theme and apply it
74
70
  style = bec_qthemes.load_stylesheet(theme)
75
71
  app.setStyleSheet(style)
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from bec_qthemes import material_icon
2
4
  from qtpy.QtCore import Property, Qt, Slot
3
5
  from qtpy.QtWidgets import QApplication, QHBoxLayout, QPushButton, QToolButton, QWidget
@@ -18,7 +20,7 @@ class DarkModeButton(BECWidget, QWidget):
18
20
  gui_id: str | None = None,
19
21
  toolbar: bool = False,
20
22
  ) -> None:
21
- super().__init__(client=client, gui_id=gui_id)
23
+ super().__init__(client=client, gui_id=gui_id, theme_update=True)
22
24
  QWidget.__init__(self, parent)
23
25
 
24
26
  self._dark_mode_enabled = False
@@ -39,6 +41,17 @@ class DarkModeButton(BECWidget, QWidget):
39
41
  self.setLayout(self.layout)
40
42
  self.setFixedSize(40, 40)
41
43
 
44
+ @Slot(str)
45
+ def apply_theme(self, theme: str):
46
+ """
47
+ Apply the theme to the widget.
48
+
49
+ Args:
50
+ theme(str, optional): The theme to be applied.
51
+ """
52
+ self.dark_mode_enabled = theme == "dark"
53
+ self.update_mode_button()
54
+
42
55
  def _get_qapp_dark_mode_state(self) -> bool:
43
56
  """
44
57
  Get the dark mode state from the QApplication.
@@ -99,30 +99,32 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
99
99
 
100
100
  self.add_legend()
101
101
  self.crosshair = None
102
- self.connect_to_theme_change()
103
- self.apply_theme()
102
+ self._connect_to_theme_change()
104
103
 
105
- def connect_to_theme_change(self):
104
+ def _connect_to_theme_change(self):
106
105
  """Connect to the theme change signal."""
107
106
  qapp = QApplication.instance()
108
107
  if hasattr(qapp, "theme_signal"):
109
- qapp.theme_signal.theme_updated.connect(self.apply_theme)
108
+ qapp.theme_signal.theme_updated.connect(self._update_theme)
110
109
 
111
110
  @Slot(str)
112
- @Slot()
113
- def apply_theme(self, theme: str | None = None):
114
- """
115
- Apply the theme to the plot widget.
116
-
117
- Args:
118
- theme(str, optional): The theme to be applied.
119
- """
111
+ def _update_theme(self, theme: str):
112
+ """Update the theme."""
120
113
  if theme is None:
121
114
  qapp = QApplication.instance()
122
115
  if hasattr(qapp, "theme"):
123
116
  theme = qapp.theme["theme"]
124
117
  else:
125
118
  theme = "dark"
119
+ self.apply_theme(theme)
120
+
121
+ def apply_theme(self, theme: str):
122
+ """
123
+ Apply the theme to the plot widget.
124
+
125
+ Args:
126
+ theme(str, optional): The theme to be applied.
127
+ """
126
128
  palette = bec_qthemes.load_palette(theme)
127
129
  text_pen = pg.mkPen(color=palette.text().color())
128
130
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.99.15
3
+ Version: 0.100.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=HE_stq5wl-0wE5ZetfEmaaDbectk20jX7Z2cxwsBegg,8348
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=_HCeY9bzET0OS8ksAlJtZPE2LccyFanuUVeUFjWVY4U,6695
5
+ CHANGELOG.md,sha256=4klTHcSrZVAZ03F0WQ1nRQLwGgHsyFC3ZrYuz_X9HdE,6664
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=qo2aifx_l3H1ofv9U1qzWJ7Y-0Kahsy79VLTF36ncgY,1334
7
+ PKG-INFO,sha256=lYGRB6sUQh1tCnb-JCVMuNj2wLacFwAud4ub2-tQsOQ,1334
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=4zOaAOMO3mwmQh3XdEw776I_hGGc4Qjw8wM2DY61zek,2544
9
+ pyproject.toml,sha256=5WM5Q3BsITnjKAY0Cij4nOk6WK8lTHot7e3wQVWbRfc,2544
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
12
12
  .gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
@@ -46,14 +46,14 @@ bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
46
46
  bec_widgets/qt_utils/error_popups.py,sha256=y9gKKWaafp468ioHr96nBhf02ZpEgjDc-BAVOTWh-e8,7680
47
47
  bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
48
48
  bec_widgets/qt_utils/settings_dialog.py,sha256=NhtzTer_xzlB2lLLrGklkI1QYLJEWQpJoZbCz4o5daI,3645
49
- bec_widgets/qt_utils/toolbar.py,sha256=NhpXw5An2qNefv0iQdCyDUbkanPcsQoD_8vDOGhQEOs,8494
49
+ bec_widgets/qt_utils/toolbar.py,sha256=oP1Lxos03MuwSTonPeILknHEXfZlKsuK13jrXoI2pck,8530
50
50
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
51
51
  bec_widgets/utils/bec_connector.py,sha256=SivHKXVyNVqeu3kCXYEPpbleTVw8g1cW0FKq1QrQgco,9987
52
52
  bec_widgets/utils/bec_designer.py,sha256=Z3MeMju-KmTz8POtm23VQfp4rvtD2sF6eIOKQkl2F7w,4729
53
53
  bec_widgets/utils/bec_dispatcher.py,sha256=NkObWO_gRO9Uobz-fy0gVTZqQsbFRaKj6fbjYZoErFI,6400
54
54
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
55
- bec_widgets/utils/bec_widget.py,sha256=vMJy-mR0kmcGaI5u1WytEuIoTJfMEcgepxIpv8yVmHY,1113
56
- bec_widgets/utils/colors.py,sha256=YuExmqsu2sbaWE2RIYGjNaGfOwZV_SmPA08B9PXm6zw,12504
55
+ bec_widgets/utils/bec_widget.py,sha256=ANFx-Ll5mjOjmILniTH5jKBITDijUtfFLb1eoiXoFws,2881
56
+ bec_widgets/utils/colors.py,sha256=N3GbVBpExfC1m_dnYFDoua-iRLM90E5kTKVOIkZVmDM,12372
57
57
  bec_widgets/utils/container_utils.py,sha256=0wr3ZfuMiAFKCrQHVjxjw-Vuk8wsHdridqcjy2eY840,1531
58
58
  bec_widgets/utils/crosshair.py,sha256=8lik9k69WI2WMj5FGLbrKtny9duxqXUJAhpX8tHoyp0,11543
59
59
  bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
@@ -110,7 +110,7 @@ bec_widgets/widgets/colormap_selector/colormap_selector_plugin.py,sha256=c5Kk4do
110
110
  bec_widgets/widgets/colormap_selector/register_colormap_selector.py,sha256=bfw7RWmTmMLTLxGT-izSwcGtxGLKvL3jdivJw2z8oN4,512
111
111
  bec_widgets/widgets/console/console.py,sha256=NG0cBuqqPX4hC-sHhk_UEkT-nHhhN9Y7karJITPLzyo,17864
112
112
  bec_widgets/widgets/dark_mode_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- bec_widgets/widgets/dark_mode_button/dark_mode_button.py,sha256=2mjLC6FiICy_xucxLlvwZPGinJoJYYDqdCbsAj1qtLs,2929
113
+ bec_widgets/widgets/dark_mode_button/dark_mode_button.py,sha256=ZvCDO_FWtEn6M1Jxaw8x8GifsulJc2NsaXNvLKAKBs0,3259
114
114
  bec_widgets/widgets/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
115
115
  bec_widgets/widgets/dark_mode_button/dark_mode_button_plugin.py,sha256=RJWeBEqR9BueUxUSuPcU-AmnzfIzt3j4jtsIacp-2Ug,1335
116
116
  bec_widgets/widgets/dark_mode_button/register_dark_mode_button.py,sha256=_4Fw6j1KLuluko8X2B7zf_DT5eA07G0CqR-aRMAn0iA,489
@@ -143,7 +143,7 @@ bec_widgets/widgets/figure/figure.py,sha256=kd7enVkT7df79HWzYjCzAZ1qF8jtlzqNfo7Y
143
143
  bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
144
  bec_widgets/widgets/figure/plots/axis_settings.py,sha256=QxRpQwgfBr1H0HTjfOpiXi_-n8I0BaZhS8LRXNeVfFg,3544
145
145
  bec_widgets/widgets/figure/plots/axis_settings.ui,sha256=a2qIuK9lyi9HCyrSvPr6wxzmm1FymaWcpmyOhMIiFt8,11013
146
- bec_widgets/widgets/figure/plots/plot_base.py,sha256=VB_erv2ITXA87NpCcYtL-Y_tTnNb9Xoqt9Z7I8XQX0I,15078
146
+ bec_widgets/widgets/figure/plots/plot_base.py,sha256=mCrQS9itby4jnwUGCQXqTQzGnP-yLZoyqI2flQvXsuc,15135
147
147
  bec_widgets/widgets/figure/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
148
  bec_widgets/widgets/figure/plots/image/image.py,sha256=y2MqgJv6Njv-huDN_exn0Fq1rAh5vs_assKCKHgQH6I,24941
149
149
  bec_widgets/widgets/figure/plots/image/image_item.py,sha256=RljjbkqJEr2cKDlqj1j5GQ1h89jpqOV-OpFz1TbED8I,10937
@@ -238,8 +238,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
238
238
  bec_widgets/widgets/website/website.py,sha256=kDlqjwtx0yft1ZNRhTdHnYh_5KZHfqT_ZGPOKT4C-yI,2619
239
239
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
240
240
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
241
- bec_widgets-0.99.15.dist-info/METADATA,sha256=qo2aifx_l3H1ofv9U1qzWJ7Y-0Kahsy79VLTF36ncgY,1334
242
- bec_widgets-0.99.15.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
243
- bec_widgets-0.99.15.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
244
- bec_widgets-0.99.15.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
245
- bec_widgets-0.99.15.dist-info/RECORD,,
241
+ bec_widgets-0.100.0.dist-info/METADATA,sha256=lYGRB6sUQh1tCnb-JCVMuNj2wLacFwAud4ub2-tQsOQ,1334
242
+ bec_widgets-0.100.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
243
+ bec_widgets-0.100.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
244
+ bec_widgets-0.100.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
245
+ bec_widgets-0.100.0.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.99.15"
7
+ version = "0.100.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [