bec-widgets 0.109.1__py3-none-any.whl → 0.111.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,31 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.111.0 (2024-09-17)
4
+
5
+ ### Documentation
6
+
7
+ * docs(position_indicator): updated position indicator documentation and added designer properties ([`60f7d54`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/60f7d54e2b4c3129de6c95729b8b4aea1757174f))
8
+
9
+ ### Feature
10
+
11
+ * feat(position_indicator): improved design and added more customization options ([`d15b222`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d15b22250fbceb708d89872c0380693e04acb107))
12
+
13
+ ### Fix
14
+
15
+ * fix(position_indicator): fixed user access ([`dd932dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dd932dd8f3910ab67ec8403124f4e176d048e542))
16
+
17
+ * fix(generate_cli): fixed type annotations ([`d3c1a1b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d3c1a1b2edcba7afea9d369820fa7974ac29c333))
18
+
19
+ * fix(positioner_box): visual improvements to the positioner_box and positioner_control_line ([`7ea4a48`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/7ea4a482e7cd9499a7268ac887b345cab01632aa))
20
+
21
+ * fix(palette viewer): fixed background for tool tip ([`9045323`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9045323049d2a39c36fc8845f3b2883d6933436b))
22
+
23
+ ## v0.110.0 (2024-09-12)
24
+
25
+ ### Feature
26
+
27
+ * feat(palette_viewer): added widget to display the current palette and accent colors ([`a8576c1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a8576c164cad17746ec4fcd5c775fb78f70c055c))
28
+
3
29
  ## v0.109.1 (2024-09-09)
4
30
 
5
31
  ### Fix
@@ -130,36 +156,6 @@
130
156
 
131
157
  * docs(buttons): buttons section of docs split to appearance and queue buttons ([`047aa26`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/047aa26a60220c826cc1375cf81daf11d1f3ab5c))
132
158
 
133
- * docs(tests): added tests tutorial for widget ([`18d8561`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/18d8561c965d149a7662085f7dbe2a39a8c4a475))
134
-
135
- ### Feature
136
-
137
- * feat(queue): BECQueue controls extended with Resume, Stop, Abort, Reset buttons ([`0d7c10e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0d7c10e670e4937787e1afaa19ca8259ac752486))
138
-
139
159
  ### Fix
140
160
 
141
161
  * fix(queue_reset_button): queue reset has to be confirmed with msgBox ([`9dd43aa`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9dd43aa1fd3991368002605df4389a7a7271011b))
142
-
143
- ### Refactor
144
-
145
- * refactor(tests): positioner box test changed to use create_widget fixture ([`df5eff3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/df5eff3147c79ff0278e6a5a09c8f73d5236aed3))
146
-
147
- ## v0.101.0 (2024-09-02)
148
-
149
- ### Feature
150
-
151
- * feat: add Dap dialog widget ([`9781b77`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9781b77de27b2810fbb1047a61b1832dd186db01))
152
-
153
- ### Refactor
154
-
155
- * refactor: add docs, cleanup ([`61ecf49`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/61ecf491e52bfbfa0d5a84764a9095310659043d))
156
-
157
- ## v0.100.0 (2024-09-01)
158
-
159
- ### Documentation
160
-
161
- * 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))
162
-
163
- ### Fix
164
-
165
- * fix(pyqt slot): removed slot decorator to avoid problems with pyqt6 ([`6c1f89a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6c1f89ad39b7240ab1d1c1123422b99ae195bf01))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.109.1
3
+ Version: 0.111.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
bec_widgets/cli/client.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # This file was automatically generated by generate_cli.py
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import enum
4
6
  from typing import Literal, Optional, overload
5
7
 
@@ -29,6 +31,7 @@ class Widgets(str, enum.Enum):
29
31
  DeviceComboBox = "DeviceComboBox"
30
32
  DeviceLineEdit = "DeviceLineEdit"
31
33
  LMFitDialog = "LMFitDialog"
34
+ PositionIndicator = "PositionIndicator"
32
35
  PositionerBox = "PositionerBox"
33
36
  PositionerControlLine = "PositionerControlLine"
34
37
  ResetButton = "ResetButton"
@@ -2539,6 +2542,45 @@ class LMFitDialog(RPCBase):
2539
2542
  """
2540
2543
 
2541
2544
 
2545
+ class PositionIndicator(RPCBase):
2546
+ @rpc_call
2547
+ def set_value(self, position: float):
2548
+ """
2549
+ None
2550
+ """
2551
+
2552
+ @rpc_call
2553
+ def set_range(self, min_value: float, max_value: float):
2554
+ """
2555
+ Set the range of the position indicator
2556
+
2557
+ Args:
2558
+ min_value(float): Minimum value of the range
2559
+ max_value(float): Maximum value of the range
2560
+ """
2561
+
2562
+ @property
2563
+ @rpc_call
2564
+ def vertical(self):
2565
+ """
2566
+ Property to determine the orientation of the position indicator
2567
+ """
2568
+
2569
+ @property
2570
+ @rpc_call
2571
+ def indicator_width(self):
2572
+ """
2573
+ Property to get the width of the indicator
2574
+ """
2575
+
2576
+ @property
2577
+ @rpc_call
2578
+ def rounded_corners(self):
2579
+ """
2580
+ Property to get the rounded corners of the position indicator
2581
+ """
2582
+
2583
+
2542
2584
  class PositionerBox(RPCBase):
2543
2585
  @rpc_call
2544
2586
  def set_positioner(self, positioner: "str | Positioner"):
@@ -31,6 +31,7 @@ else:
31
31
  class ClientGenerator:
32
32
  def __init__(self):
33
33
  self.header = """# This file was automatically generated by generate_cli.py\n
34
+ from __future__ import annotations
34
35
  import enum
35
36
  from typing import Literal, Optional, overload
36
37
 
@@ -0,0 +1,183 @@
1
+ from qtpy.QtCore import Qt
2
+ from qtpy.QtWidgets import (
3
+ QApplication,
4
+ QFrame,
5
+ QGridLayout,
6
+ QHBoxLayout,
7
+ QLabel,
8
+ QScrollArea,
9
+ QSizePolicy,
10
+ QVBoxLayout,
11
+ QWidget,
12
+ )
13
+
14
+ from bec_widgets.utils.bec_widget import BECWidget
15
+ from bec_widgets.utils.colors import get_accent_colors, get_theme_palette
16
+ from bec_widgets.widgets.dark_mode_button.dark_mode_button import DarkModeButton
17
+
18
+
19
+ class PaletteViewer(BECWidget, QWidget):
20
+ """
21
+ This class is a widget that displays current palette colors.
22
+ """
23
+
24
+ ICON_NAME = "palette"
25
+
26
+ def __init__(self, *args, parent=None, **kwargs):
27
+ super().__init__(*args, theme_update=True, **kwargs)
28
+ QWidget.__init__(self, parent=parent)
29
+ self.setFixedSize(400, 600)
30
+ layout = QVBoxLayout(self)
31
+ dark_mode_button = DarkModeButton(self)
32
+ layout.addWidget(dark_mode_button)
33
+
34
+ # Create a scroll area to hold the color boxes
35
+ scroll_area = QScrollArea(self)
36
+ scroll_area.setWidgetResizable(True)
37
+ scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
38
+
39
+ # Create a frame to hold the color boxes
40
+ self.frame = QFrame(self)
41
+ self.frame_layout = QGridLayout(self.frame)
42
+ self.frame_layout.setSpacing(0)
43
+ self.frame_layout.setContentsMargins(0, 0, 0, 0)
44
+
45
+ scroll_area.setWidget(self.frame)
46
+ layout.addWidget(scroll_area)
47
+
48
+ self.setLayout(layout)
49
+
50
+ self.update_palette()
51
+
52
+ def apply_theme(self, theme) -> None:
53
+ """
54
+ Apply the theme to the widget.
55
+
56
+ Args:
57
+ theme (str): The theme to apply.
58
+ """
59
+ self.update_palette()
60
+
61
+ def clear_palette(self) -> None:
62
+ """
63
+ Clear the palette colors from the frame.
64
+ Recursively removes all widgets and layouts in the frame layout.
65
+ """
66
+ # Iterate over all items in the layout in reverse to safely remove them
67
+ for i in reversed(range(self.frame_layout.count())):
68
+ item = self.frame_layout.itemAt(i)
69
+
70
+ # If the item is a layout, clear its contents
71
+ if isinstance(item, QHBoxLayout):
72
+ # Recursively remove all widgets from the layout
73
+ for j in reversed(range(item.count())):
74
+ widget = item.itemAt(j).widget()
75
+ if widget:
76
+ item.removeWidget(widget)
77
+ widget.deleteLater()
78
+ self.frame_layout.removeItem(item)
79
+
80
+ # If the item is a widget, remove and delete it
81
+ elif item.widget():
82
+ widget = item.widget()
83
+ self.frame_layout.removeWidget(widget)
84
+ widget.deleteLater()
85
+
86
+ def update_palette(self) -> None:
87
+ """
88
+ Update the palette colors in the frame.
89
+ """
90
+ self.clear_palette()
91
+ palette_label = QLabel("Palette Colors (e.g. palette.windowText().color())")
92
+ palette_label.setStyleSheet("font-weight: bold;")
93
+ self.frame_layout.addWidget(palette_label, 0, 0)
94
+
95
+ palette = get_theme_palette()
96
+ # Add the palette colors (roles) to the frame
97
+ palette_roles = [
98
+ palette.windowText,
99
+ palette.toolTipText,
100
+ palette.placeholderText,
101
+ palette.text,
102
+ palette.buttonText,
103
+ palette.highlight,
104
+ palette.link,
105
+ palette.light,
106
+ palette.midlight,
107
+ palette.mid,
108
+ palette.shadow,
109
+ palette.button,
110
+ palette.brightText,
111
+ palette.toolTipBase,
112
+ palette.alternateBase,
113
+ palette.dark,
114
+ palette.base,
115
+ palette.window,
116
+ palette.highlightedText,
117
+ palette.linkVisited,
118
+ ]
119
+
120
+ offset = 1
121
+ for i, pal in enumerate(palette_roles):
122
+ i += offset
123
+ color = pal().color()
124
+ label_layout = QHBoxLayout()
125
+ color_label = QLabel(f"{pal().color().name()} ({pal.__name__})")
126
+ background_label = self.background_label_with_clipboard(color)
127
+ label_layout.addWidget(color_label)
128
+ label_layout.addWidget(background_label)
129
+ self.frame_layout.addLayout(label_layout, i, 0)
130
+
131
+ # add a horizontal spacer
132
+ spacer = QLabel()
133
+ spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
134
+ self.frame_layout.addWidget(spacer, i + 1, 0)
135
+
136
+ accent_colors_label = QLabel("Accent Colors (e.g. accent_colors.default)")
137
+ accent_colors_label.setStyleSheet("font-weight: bold;")
138
+ self.frame_layout.addWidget(accent_colors_label, i + 2, 0)
139
+
140
+ accent_colors = get_accent_colors()
141
+ items = [
142
+ (accent_colors.default, "default"),
143
+ (accent_colors.success, "success"),
144
+ (accent_colors.warning, "warning"),
145
+ (accent_colors.emergency, "emergency"),
146
+ (accent_colors.highlight, "highlight"),
147
+ ]
148
+
149
+ offset = len(palette_roles) + 2
150
+ for i, (color, name) in enumerate(items):
151
+ i += offset
152
+ label_layout = QHBoxLayout()
153
+ color_label = QLabel(f"{color.name()} ({name})")
154
+ background_label = self.background_label_with_clipboard(color)
155
+ label_layout.addWidget(color_label)
156
+ label_layout.addWidget(background_label)
157
+ self.frame_layout.addLayout(label_layout, i + 2, 0)
158
+
159
+ def background_label_with_clipboard(self, color) -> QLabel:
160
+ """
161
+ Create a label with a background color that copies the color to the clipboard when clicked.
162
+
163
+ Args:
164
+ color (QColor): The color to display in the background.
165
+
166
+ Returns:
167
+ QLabel: The label with the background color.
168
+ """
169
+ button = QLabel()
170
+ button.setStyleSheet(f"QLabel {{ background-color: {color.name()}; }}")
171
+ button.setToolTip("Click to copy color to clipboard")
172
+ button.setCursor(Qt.PointingHandCursor)
173
+ button.mousePressEvent = lambda event: QApplication.clipboard().setText(color.name())
174
+ return button
175
+
176
+
177
+ if __name__ == "__main__": # pragma: no cover
178
+ import sys
179
+
180
+ app = QApplication(sys.argv)
181
+ viewer = PaletteViewer()
182
+ viewer.show()
183
+ sys.exit(app.exec_())
@@ -1,67 +1,285 @@
1
- from qtpy.QtCore import Qt, Slot
2
- from qtpy.QtGui import QPainter, QPen
1
+ import numpy as np
2
+ from qtpy.QtCore import Property, QSize, Qt, Slot
3
+ from qtpy.QtGui import QBrush, QColor, QPainter, QPainterPath, QPen
3
4
  from qtpy.QtWidgets import QWidget
4
5
 
6
+ from bec_widgets.utils.bec_widget import BECWidget
7
+ from bec_widgets.utils.colors import get_accent_colors, get_theme_palette
5
8
 
6
- class PositionIndicator(QWidget):
9
+
10
+ class PositionIndicator(BECWidget, QWidget):
11
+ USER_ACCESS = ["set_value", "set_range", "vertical", "indicator_width", "rounded_corners"]
7
12
 
8
13
  ICON_NAME = "horizontal_distribute"
9
14
 
10
- def __init__(self, parent=None):
11
- super().__init__(parent)
12
- self.position = 0.5
15
+ def __init__(self, parent=None, client=None, config=None, gui_id=None):
16
+ super().__init__(client=client, config=config, gui_id=gui_id)
17
+ QWidget.__init__(self, parent=parent)
18
+ self.position = 50
13
19
  self.min_value = 0
14
20
  self.max_value = 100
15
21
  self.scaling_factor = 0.5
16
- self.setMinimumHeight(10)
22
+ self.is_vertical = False
23
+ self._current_indicator_position = 0
24
+ self._draw_position = 0
25
+ self._rounded_corners = 10
26
+ self._indicator_width = 2
27
+ self._indicator_color = get_accent_colors().success
28
+ self._background_color = get_theme_palette().mid().color()
29
+ self._use_color_palette = True
30
+
31
+ def set_range(self, min_value: float, max_value: float):
32
+ """
33
+ Set the range of the position indicator
34
+
35
+ Args:
36
+ min_value(float): Minimum value of the range
37
+ max_value(float): Maximum value of the range
38
+ """
39
+ self.minimum = min_value
40
+ self.maximum = max_value
41
+
42
+ @Property(float)
43
+ def minimum(self):
44
+ """
45
+ Property to get the minimum value of the position indicator
46
+ """
47
+ return self.min_value
17
48
 
18
- def set_range(self, min_value, max_value):
49
+ @minimum.setter
50
+ def minimum(self, min_value: float):
51
+ """
52
+ Setter for the minimum property
53
+
54
+ Args:
55
+ min_value: The minimum value of the position indicator
56
+ """
19
57
  self.min_value = min_value
58
+ self.update()
59
+
60
+ @Property(float)
61
+ def maximum(self):
62
+ """
63
+ Property to get the maximum value of the position indicator
64
+ """
65
+ return self.max_value
66
+
67
+ @maximum.setter
68
+ def maximum(self, max_value: float):
69
+ """
70
+ Setter for the maximum property
71
+
72
+ Args:
73
+ max_value: The maximum value of the position indicator
74
+ """
20
75
  self.max_value = max_value
76
+ self.update()
77
+
78
+ @Property(bool)
79
+ def vertical(self):
80
+ """
81
+ Property to determine the orientation of the position indicator
82
+ """
83
+ return self.is_vertical
84
+
85
+ @vertical.setter
86
+ def vertical(self, is_vertical: bool):
87
+ """
88
+ Setter for the vertical property
89
+
90
+ Args:
91
+ is_vertical: True if the indicator should be vertical, False if horizontal
92
+ """
93
+
94
+ self.is_vertical = is_vertical
95
+ self.update()
96
+
97
+ @Property(float)
98
+ def value(self):
99
+ """
100
+ Property to get the current value of the position indicator
101
+ """
102
+ return self.position
103
+
104
+ @value.setter
105
+ def value(self, position: float):
106
+ """
107
+ Setter for the value property
108
+
109
+ Args:
110
+ position: The new position of the indicator
111
+ """
112
+ self.set_value(position)
113
+
114
+ @Property(int)
115
+ def indicator_width(self):
116
+ """
117
+ Property to get the width of the indicator
118
+ """
119
+ return self._indicator_width
120
+
121
+ @indicator_width.setter
122
+ def indicator_width(self, width: int):
123
+ """
124
+ Setter for the indicator width property
125
+
126
+ Args:
127
+ width: The new width of the indicator
128
+ """
129
+ self._indicator_width = width
130
+ self.update()
131
+
132
+ @Property(int)
133
+ def rounded_corners(self):
134
+ """
135
+ Property to get the rounded corners of the position indicator
136
+ """
137
+ return self._rounded_corners
138
+
139
+ @rounded_corners.setter
140
+ def rounded_corners(self, value: int):
141
+ """
142
+ Setter for the rounded corners property
143
+
144
+ Args:
145
+ value: The new value for the rounded corners
146
+ """
147
+ self._rounded_corners = value
148
+ self.update()
21
149
 
150
+ @Property(QColor)
151
+ def indicator_color(self):
152
+ """
153
+ Property to get the color of the indicator
154
+ """
155
+ return self._indicator_color
156
+
157
+ @indicator_color.setter
158
+ def indicator_color(self, color: QColor):
159
+ """
160
+ Setter for the indicator color property
161
+
162
+ Args:
163
+ color: The new color for the indicator
164
+ """
165
+ self._indicator_color = color
166
+ self.update()
167
+
168
+ @Property(QColor)
169
+ def background_color(self):
170
+ """
171
+ Property to get the background color of the position indicator
172
+ """
173
+ return self._background_color
174
+
175
+ @background_color.setter
176
+ def background_color(self, color: QColor):
177
+ """
178
+ Setter for the background color property
179
+
180
+ Args:
181
+ color: The new background color
182
+ """
183
+ self._background_color = color
184
+ self.update()
185
+
186
+ @Property(bool)
187
+ def use_color_palette(self):
188
+ """
189
+ Property to determine if the indicator should use the color palette or the custom color.
190
+ """
191
+ return self._use_color_palette
192
+
193
+ @use_color_palette.setter
194
+ def use_color_palette(self, use_palette: bool):
195
+ """
196
+ Setter for the use color palette property
197
+
198
+ Args:
199
+ use_palette: True if the indicator should use the color palette, False if custom color
200
+ """
201
+ self._use_color_palette = use_palette
202
+ self.update()
203
+
204
+ # @Property(float)
205
+ @Slot(int)
22
206
  @Slot(float)
23
- def on_position_update(self, position: float):
207
+ def set_value(self, position: float):
24
208
  self.position = position
25
209
  self.update()
26
210
 
211
+ def _get_indicator_color(self):
212
+ if self._use_color_palette:
213
+ return get_accent_colors().success
214
+ return self._indicator_color
215
+
216
+ def _get_background_brush(self):
217
+ if self._use_color_palette:
218
+ return get_theme_palette().mid()
219
+ return QBrush(self._background_color)
220
+
27
221
  def paintEvent(self, event):
28
222
  painter = QPainter(self)
29
- painter.setRenderHint(QPainter.Antialiasing)
30
-
31
223
  width = self.width()
32
224
  height = self.height()
33
225
 
34
- # Draw horizontal line
35
- painter.setPen(Qt.black)
36
- painter.drawLine(0, height // 2, width, height // 2)
37
-
38
- # Draw shorter vertical line at the current position
39
- x_pos = int(self.position * width)
40
- painter.setPen(QPen(Qt.red, 2))
41
- short_line_height = int(height * self.scaling_factor)
42
- painter.drawLine(
43
- x_pos,
44
- (height // 2) - (short_line_height // 2),
45
- x_pos,
46
- (height // 2) + (short_line_height // 2),
226
+ # Set up the brush for the background
227
+ painter.setBrush(self._get_background_brush())
228
+
229
+ # Create a QPainterPath with a rounded rectangle for clipping
230
+ path = QPainterPath()
231
+ path.addRoundedRect(0, 0, width, height, self._rounded_corners, self._rounded_corners)
232
+
233
+ # Set clipping to the rounded rectangle
234
+ painter.setClipPath(path)
235
+
236
+ # Draw the rounded rectangle background first
237
+ painter.setPen(Qt.NoPen)
238
+ painter.drawRoundedRect(0, 0, width, height, self._rounded_corners, self._rounded_corners)
239
+
240
+ # get the position scaled to the defined min and max values
241
+ self._current_indicator_position = position = np.interp(
242
+ self.position, [self.min_value, self.max_value], [0, 100]
47
243
  )
48
244
 
49
- # Draw thicker vertical lines at the ends
50
- end_line_pen = QPen(Qt.blue, 5)
51
- painter.setPen(end_line_pen)
52
- painter.drawLine(0, 0, 0, height)
53
- painter.drawLine(width - 1, 0, width - 1, height)
245
+ if self.is_vertical:
246
+ # If vertical, rotate the coordinate system by -90 degrees
247
+ painter.translate(width // 2, height // 2) # Move origin to center
248
+ painter.rotate(-90) # Rotate by -90 degrees for vertical drawing
249
+ painter.translate(-height // 2, -width // 2) # Restore the origin for drawing
250
+
251
+ # Switch width and height for the vertical orientation
252
+ width, height = height, width
54
253
 
254
+ # Draw the moving vertical indicator, respecting the clip path
255
+ self._draw_position = x_pos = round(
256
+ position * width / 100
257
+ ) # Position for the vertical line
55
258
 
56
- if __name__ == "__main__":
259
+ indicator_pen = QPen(self._get_indicator_color(), self._indicator_width)
260
+ painter.setPen(indicator_pen)
261
+ painter.drawLine(x_pos, 0, x_pos, height)
262
+
263
+ painter.end()
264
+
265
+ def minimumSizeHint(self):
266
+ # Set the smallest possible size
267
+ return QSize(10, 10)
268
+
269
+
270
+ if __name__ == "__main__": # pragma: no cover
271
+ from bec_qthemes import setup_theme
57
272
  from qtpy.QtWidgets import QApplication, QSlider, QVBoxLayout
58
273
 
59
274
  app = QApplication([])
60
-
275
+ setup_theme("dark")
276
+ # Create position indicator and slider
61
277
  position_indicator = PositionIndicator()
278
+ # position_indicator.set_range(0, 1)
62
279
  slider = QSlider(Qt.Horizontal)
63
- slider.valueChanged.connect(lambda value: position_indicator.on_position_update(value / 100))
64
-
280
+ slider.valueChanged.connect(lambda value: position_indicator.set_value(value))
281
+ position_indicator.is_vertical = False
282
+ # position_indicator.set_value(100)
65
283
  layout = QVBoxLayout()
66
284
  layout.addWidget(position_indicator)
67
285
  layout.addWidget(slider)
@@ -16,7 +16,7 @@ from qtpy.QtWidgets import QDialog, QDoubleSpinBox, QPushButton, QVBoxLayout, QW
16
16
 
17
17
  from bec_widgets.utils import UILoader
18
18
  from bec_widgets.utils.bec_widget import BECWidget
19
- from bec_widgets.utils.colors import set_theme
19
+ from bec_widgets.utils.colors import get_accent_colors, set_theme
20
20
  from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
21
21
 
22
22
  logger = bec_logger.logger
@@ -73,6 +73,10 @@ class PositionerBox(BECWidget, QWidget):
73
73
 
74
74
  self.ui.step_size.setStepType(QDoubleSpinBox.AdaptiveDecimalStepType)
75
75
  self.ui.stop.clicked.connect(self.on_stop)
76
+ self.ui.stop.setToolTip("Stop")
77
+ self.ui.stop.setStyleSheet(
78
+ f"QPushButton {{background-color: {get_accent_colors().emergency.name()}; color: white;}}"
79
+ )
76
80
  self.ui.tweak_right.clicked.connect(self.on_tweak_right)
77
81
  self.ui.tweak_right.setToolTip("Tweak right")
78
82
  self.ui.tweak_left.clicked.connect(self.on_tweak_left)
@@ -249,7 +253,7 @@ class PositionerBox(BECWidget, QWidget):
249
253
  self.update_limits(limits)
250
254
  if limits is not None and readback_val is not None and limits[0] != limits[1]:
251
255
  pos = (readback_val - limits[0]) / (limits[1] - limits[0])
252
- self.ui.position_indicator.on_position_update(pos)
256
+ self.ui.position_indicator.set_value(pos)
253
257
 
254
258
  def update_limits(self, limits: tuple):
255
259
  """Update limits
@@ -170,7 +170,20 @@
170
170
  </layout>
171
171
  </item>
172
172
  <item>
173
- <widget class="PositionIndicator" name="position_indicator"/>
173
+ <widget class="PositionIndicator" name="position_indicator">
174
+ <property name="maximum" stdset="0">
175
+ <double>1.000000000000000</double>
176
+ </property>
177
+ <property name="value" stdset="0">
178
+ <double>0.500000000000000</double>
179
+ </property>
180
+ <property name="indicator_width" stdset="0">
181
+ <number>4</number>
182
+ </property>
183
+ <property name="rounded_corners" stdset="0">
184
+ <number>4</number>
185
+ </property>
186
+ </widget>
174
187
  </item>
175
188
  <item>
176
189
  <widget class="QLabel" name="readback">
@@ -24,11 +24,9 @@ class PositionerControlLine(PositionerBox):
24
24
  if __name__ == "__main__": # pragma: no cover
25
25
  import sys
26
26
 
27
- import qdarktheme
28
27
  from qtpy.QtWidgets import QApplication
29
28
 
30
29
  app = QApplication(sys.argv)
31
- qdarktheme.setup_theme("dark")
32
30
  widget = PositionerControlLine(device="samy")
33
31
 
34
32
  widget.show()
@@ -6,7 +6,7 @@
6
6
  <rect>
7
7
  <x>0</x>
8
8
  <y>0</y>
9
- <width>785</width>
9
+ <width>612</width>
10
10
  <height>91</height>
11
11
  </rect>
12
12
  </property>
@@ -59,16 +59,6 @@
59
59
  </item>
60
60
  <item>
61
61
  <layout class="QHBoxLayout" name="horizontalLayout_2">
62
- <item>
63
- <widget class="PositionIndicator" name="position_indicator">
64
- <property name="minimumSize">
65
- <size>
66
- <width>80</width>
67
- <height>10</height>
68
- </size>
69
- </property>
70
- </widget>
71
- </item>
72
62
  <item>
73
63
  <widget class="SpinnerWidget" name="spinner_widget">
74
64
  <property name="minimumSize">
@@ -139,14 +129,14 @@
139
129
  <widget class="QToolButton" name="tweak_left">
140
130
  <property name="minimumSize">
141
131
  <size>
142
- <width>30</width>
143
- <height>30</height>
132
+ <width>25</width>
133
+ <height>25</height>
144
134
  </size>
145
135
  </property>
146
136
  <property name="maximumSize">
147
137
  <size>
148
- <width>30</width>
149
- <height>30</height>
138
+ <width>25</width>
139
+ <height>25</height>
150
140
  </size>
151
141
  </property>
152
142
  <property name="text">
@@ -154,8 +144,8 @@
154
144
  </property>
155
145
  <property name="iconSize">
156
146
  <size>
157
- <width>30</width>
158
- <height>30</height>
147
+ <width>25</width>
148
+ <height>25</height>
159
149
  </size>
160
150
  </property>
161
151
  <property name="arrowType">
@@ -170,14 +160,14 @@
170
160
  <widget class="QToolButton" name="tweak_right">
171
161
  <property name="minimumSize">
172
162
  <size>
173
- <width>30</width>
174
- <height>30</height>
163
+ <width>25</width>
164
+ <height>25</height>
175
165
  </size>
176
166
  </property>
177
167
  <property name="maximumSize">
178
168
  <size>
179
- <width>30</width>
180
- <height>30</height>
169
+ <width>25</width>
170
+ <height>25</height>
181
171
  </size>
182
172
  </property>
183
173
  <property name="text">
@@ -185,8 +175,8 @@
185
175
  </property>
186
176
  <property name="iconSize">
187
177
  <size>
188
- <width>30</width>
189
- <height>30</height>
178
+ <width>25</width>
179
+ <height>25</height>
190
180
  </size>
191
181
  </property>
192
182
  <property name="arrowType">
@@ -194,6 +184,34 @@
194
184
  </property>
195
185
  </widget>
196
186
  </item>
187
+ <item>
188
+ <widget class="PositionIndicator" name="position_indicator">
189
+ <property name="minimumSize">
190
+ <size>
191
+ <width>15</width>
192
+ <height>10</height>
193
+ </size>
194
+ </property>
195
+ <property name="maximumSize">
196
+ <size>
197
+ <width>15</width>
198
+ <height>16777215</height>
199
+ </size>
200
+ </property>
201
+ <property name="maximum" stdset="0">
202
+ <double>1.000000000000000</double>
203
+ </property>
204
+ <property name="vertical" stdset="0">
205
+ <bool>true</bool>
206
+ </property>
207
+ <property name="value" stdset="0">
208
+ <double>0.500000000000000</double>
209
+ </property>
210
+ <property name="rounded_corners" stdset="0">
211
+ <number>2</number>
212
+ </property>
213
+ </widget>
214
+ </item>
197
215
  </layout>
198
216
  </widget>
199
217
  </item>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.109.1
3
+ Version: 0.111.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=Dc1iDjsc72UxdUtihx4uSZU0lrTQeR8hZwGx1MQBfKE,8432
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=83toIm-bLOmMXqLc9D_TuEkaAmajXcVh2gp_jSZ0N1o,7266
5
+ CHANGELOG.md,sha256=a5ZyzKXWOFBwFhAuDUsCdYs2qvAQfdOKgL6rTvP7kMI,7303
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=zZkCksUj3vS0F-9_qaUXWatTcIGMUxtUYALlYIAmQeo,1334
7
+ PKG-INFO,sha256=3iF5RveygG826BQFq8Y42AzHUa_oW3XDNDPYNMZAZEI,1334
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=Acf6n5A69AFyAgZ3AJrP3hmbHsi7XEZNGXe0ic-zuDE,2544
9
+ pyproject.toml,sha256=6iAGLuN-mkPkjymMUKn_BAv-fR96kbMeQdDDXehNYUU,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
@@ -22,9 +22,9 @@ bec_widgets/assets/status_icons/running.svg,sha256=nlc6rKh_f-uOxQSk0BkBNyWnPAJU5
22
22
  bec_widgets/assets/status_icons/warning.svg,sha256=CNx88p9kbDG51s9ztKf-cfYan4JdDBbk3-IFKfOOFlI,364
23
23
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
24
24
  bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
25
- bec_widgets/cli/client.py,sha256=_sgO24vbZnc-dRPZjH_sDfvYHHvR-OeYkQmr_oGuSbU,81230
25
+ bec_widgets/cli/client.py,sha256=PaNh9ih6HXlOEDo6MHa4L3Yl3pjZSWZ0bCk-2G7RWiU,82154
26
26
  bec_widgets/cli/client_utils.py,sha256=EdDfo3uuYAWtZiDGGu3_GPnl94FSLkNG2N_4I9FNfMc,11809
27
- bec_widgets/cli/generate_cli.py,sha256=zRhhcErjHqnNymoxu9oqeUZUfwLX84De1RIeGiZGUyY,6602
27
+ bec_widgets/cli/generate_cli.py,sha256=C5SOlUeDzFgEptgpa5vdiF6c-YILLcfILZZtk9jr_H0,6637
28
28
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
29
29
  bec_widgets/cli/rpc_wigdet_handler.py,sha256=6kQng2DyS6rhLJqSJ7xa0kdgSxp-35A2upcf833dJRE,1483
30
30
  bec_widgets/cli/server.py,sha256=KfZ0W2OKb1UeqkR0buXrdVF4MpznzyLw9EQtGzEBkvI,8833
@@ -44,6 +44,7 @@ bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=MFMwONn4EZ3
44
44
  bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-60zjQ2FAs88Ldjm1MfoMROfiQZZu6Guav8,2379
45
45
  bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  bec_widgets/qt_utils/error_popups.py,sha256=y9gKKWaafp468ioHr96nBhf02ZpEgjDc-BAVOTWh-e8,7680
47
+ bec_widgets/qt_utils/palette_viewer.py,sha256=PGhJ-4XI0f7gNnC1djNgcIHYg6HDO6hPju4pfWj9rvg,6311
47
48
  bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
48
49
  bec_widgets/qt_utils/settings_dialog.py,sha256=NhtzTer_xzlB2lLLrGklkI1QYLJEWQpJoZbCz4o5daI,3645
49
50
  bec_widgets/qt_utils/toolbar.py,sha256=QMXTbEFowVzbQzblXZVJcAhgd_zrqaqBISyd4QlPv1A,8576
@@ -187,18 +188,18 @@ bec_widgets/widgets/motor_map/motor_map_dialog/__init__.py,sha256=47DEQpj8HBSa-_
187
188
  bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py,sha256=-VsVe1yZ41heD2JyknsbFOa9MMThg-G7JPoaJc5ZbYg,2259
188
189
  bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.ui,sha256=nv5vPftt6vcIl60OOZLRvwD29rdHVWOoGmz168BnwKw,2685
189
190
  bec_widgets/widgets/position_indicator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
- bec_widgets/widgets/position_indicator/position_indicator.py,sha256=nxmz7zqKhJsWqjH9hPzncTY07dNt-I2UzqiXhmoK4vo,2061
191
+ bec_widgets/widgets/position_indicator/position_indicator.py,sha256=GVUmq4pdd-Vc8r9KWqH4G27ZFkdjNpiXgeirJ5_F_2w,8581
191
192
  bec_widgets/widgets/position_indicator/position_indicator.pyproject,sha256=s0JEf5YkpMag19ddFSYeRZ8erBau7erO3bqw05YrTyg,36
192
193
  bec_widgets/widgets/position_indicator/position_indicator_plugin.py,sha256=ehQPpwkjJ7k365i4gdwtmAmCbVmB1tvQLEo60J_ivo4,1413
193
194
  bec_widgets/widgets/position_indicator/register_position_indicator.py,sha256=OZNiMgM_80TPSAXK_0hXAkne4vUh8DGvh_OdpOiMpwI,516
194
195
  bec_widgets/widgets/positioner_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
- bec_widgets/widgets/positioner_box/positioner_box.py,sha256=9k1i5o_8lxZApMTmy1k0nwkbGedFHph25oYPKXZ9pgo,11304
196
+ bec_widgets/widgets/positioner_box/positioner_box.py,sha256=j2NblvZI1g_ltnAdjHNUj4cXa6mHM-jv3CO-uyK_nOI,11503
196
197
  bec_widgets/widgets/positioner_box/positioner_box.pyproject,sha256=7966pHdDseaHciaPNEKgdQgbUThSZf5wEDCeAEJh9po,32
197
- bec_widgets/widgets/positioner_box/positioner_box.ui,sha256=Y-Xp0z32okT7X4-rL5r7dF_QH_QpXvPes3f778cC7_k,5633
198
+ bec_widgets/widgets/positioner_box/positioner_box.ui,sha256=7LZlM9smIqmkvS2KAIDkBamn04mBAkXeG9T1fpKRQe8,6093
198
199
  bec_widgets/widgets/positioner_box/positioner_box_plugin.py,sha256=kJtQgRFGkJYWbZqJ7K7o0UhdsgAlODUVZL8pKJWwMhs,1413
199
- bec_widgets/widgets/positioner_box/positioner_control_line.py,sha256=TfnTuzpq9zSERVhNTygSZUx9B--_7UIFGyk1VVonSgQ,946
200
+ bec_widgets/widgets/positioner_box/positioner_control_line.py,sha256=qouUH2gcO4ZczYqQk1g7LWNFv4m-orQdx86MK0PkXuc,889
200
201
  bec_widgets/widgets/positioner_box/positioner_control_line.pyproject,sha256=RGIXDjWq3fNCgOnU-08oeIeBLCcjYbRXgyh26drxB7I,41
201
- bec_widgets/widgets/positioner_box/positioner_control_line.ui,sha256=hJ4e3e3A1zZY3WRfQ7yvAZUAtL8tJhCJX2bWbtty_EQ,5625
202
+ bec_widgets/widgets/positioner_box/positioner_control_line.ui,sha256=fUq56Bl05jxy81KKlaP9B52lZDDrCjUxMTjMCNFiukw,6170
202
203
  bec_widgets/widgets/positioner_box/positioner_control_line_plugin.py,sha256=ud3KqPoW_jDipe6O7uEbM_X0M7angJgchY9dAjyxNRM,1495
203
204
  bec_widgets/widgets/positioner_box/register_positioner_box.py,sha256=UPOUjXXq6-IgSj0kdV_nJe1rYPMF8aIZxF4eSmWgQAg,483
204
205
  bec_widgets/widgets/positioner_box/register_positioner_control_line.py,sha256=MJ13vKGIwTMQGFhll63tfUGXHyd6bz40Cvr85oYKH3I,525
@@ -255,8 +256,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
255
256
  bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
256
257
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
257
258
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
258
- bec_widgets-0.109.1.dist-info/METADATA,sha256=zZkCksUj3vS0F-9_qaUXWatTcIGMUxtUYALlYIAmQeo,1334
259
- bec_widgets-0.109.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
260
- bec_widgets-0.109.1.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
261
- bec_widgets-0.109.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
262
- bec_widgets-0.109.1.dist-info/RECORD,,
259
+ bec_widgets-0.111.0.dist-info/METADATA,sha256=3iF5RveygG826BQFq8Y42AzHUa_oW3XDNDPYNMZAZEI,1334
260
+ bec_widgets-0.111.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
261
+ bec_widgets-0.111.0.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
262
+ bec_widgets-0.111.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
263
+ bec_widgets-0.111.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.109.1"
7
+ version = "0.111.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [