bec-widgets 0.94.3__py3-none-any.whl → 0.94.5__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.94.5 (2024-08-14)
4
+
5
+ ### Build
6
+
7
+ * build: increased min version of bec to 2.21.4
8
+
9
+ Since we now rely on reusing the BECClient singleton, we need the fix introduced with 2.21.4 in BEC. ([`4f96d0e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f96d0e4a14edc4b2839c1dddeda384737dc7a8a))
10
+
11
+ ### Fix
12
+
13
+ * fix(rpc): use client singleton instead of dispatcher ([`ea9240d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ea9240d2f71931082f33fb6b68231469875c3d63))
14
+
15
+ * fix: removed qcoreapplication for polling events ([`4d02b42`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4d02b42f11e9882b843317255a4975565c8a536f))
16
+
17
+ ## v0.94.4 (2024-08-14)
18
+
19
+ ### Documentation
20
+
21
+ * docs: review developer section; add introduction ([`2af5c94`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2af5c94913a3435c1839034df4f45f885b56d08b))
22
+
23
+ ### Fix
24
+
25
+ * fix: do not shutdown client in "close"
26
+
27
+ Terminating client connections has to be done at the application level ([`198c1d1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/198c1d1064cc2dae55de4b941929341faddacb28))
28
+
3
29
  ## v0.94.3 (2024-08-13)
4
30
 
5
31
  ### Fix
@@ -129,23 +155,3 @@ This reverts commit fd6ae91993a23a7b8dbb2cf3c4b7c3eda6d2b0f6 ([`5aad401`](https:
129
155
  * fix: fix missmatch of signal/slot in image and motormap ([`dcc5fd7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dcc5fd71ee9f51767a7b2b1ed6200e89d1ef754c))
130
156
 
131
157
  ## v0.92.3 (2024-07-28)
132
-
133
- ### Fix
134
-
135
- * fix(docs): moved to pyside6 ([`71873dd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/71873ddf359516ded8f74f4d2f73df4156aa1368))
136
-
137
- ## v0.92.2 (2024-07-28)
138
-
139
- ### Fix
140
-
141
- * fix(widgets): fixed import for tictactoe example ([`995a795`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/995a795060bebe25c17108d80ae0fa30463f03b1))
142
-
143
- ## v0.92.1 (2024-07-28)
144
-
145
- ### Fix
146
-
147
- * fix: use SafeSlot instead of Slot ([`bc1e239`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bc1e23944cc0e5a861e3d0b4dc5b4ac6292d5269))
148
-
149
- * fix: linting ([`a3fe205`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a3fe20500ae2ac03dcde07432f7e21ce5262ce46))
150
-
151
- * fix: always add a QApplication for tests ([`61a4e32`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/61a4e32deb337ed27f2f43358b88b7266413b58e))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.94.3
3
+ Version: 0.94.5
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
@@ -9,8 +9,8 @@ Classifier: Development Status :: 3 - Alpha
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Topic :: Scientific/Engineering
11
11
  Requires-Python: >=3.10
12
- Requires-Dist: bec-ipython-client~=2.16
13
- Requires-Dist: bec-lib~=2.16
12
+ Requires-Dist: bec-ipython-client>=2.21.4,~=2.21
13
+ Requires-Dist: bec-lib>=2.21.4,~=2.21
14
14
  Requires-Dist: bec-qthemes~=0.0
15
15
  Requires-Dist: black~=24.0
16
16
  Requires-Dist: isort>=5.13.2,~=5.13
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import threading
4
+ from queue import Queue
3
5
  from typing import TYPE_CHECKING
4
6
 
5
7
  from pydantic import BaseModel
@@ -25,6 +27,17 @@ class AutoUpdates:
25
27
 
26
28
  def __init__(self, gui: BECDockArea):
27
29
  self.gui = gui
30
+ self.msg_queue = Queue()
31
+ self.auto_update_thread = None
32
+ self._shutdown_sentinel = object()
33
+ self.start()
34
+
35
+ def start(self):
36
+ """
37
+ Start the auto update thread.
38
+ """
39
+ self.auto_update_thread = threading.Thread(target=self.process_queue)
40
+ self.auto_update_thread.start()
28
41
 
29
42
  def start_default_dock(self):
30
43
  """
@@ -79,6 +92,16 @@ class AutoUpdates:
79
92
  info = self.get_scan_info(msg)
80
93
  self.handler(info)
81
94
 
95
+ def process_queue(self):
96
+ """
97
+ Process the message queue.
98
+ """
99
+ while True:
100
+ msg = self.msg_queue.get()
101
+ if msg is self._shutdown_sentinel:
102
+ break
103
+ self.run(msg)
104
+
82
105
  @staticmethod
83
106
  def get_selected_device(monitored_devices, selected_device):
84
107
  """
@@ -151,3 +174,11 @@ class AutoUpdates:
151
174
  fig.clear_all()
152
175
  plt = fig.plot(x_name=dev_x, y_name=dev_y, label=f"Scan {info.scan_number} - {dev_y}")
153
176
  plt.set(title=f"Scan {info.scan_number}", x_label=dev_x, y_label=dev_y)
177
+
178
+ def shutdown(self):
179
+ """
180
+ Shutdown the auto update thread.
181
+ """
182
+ self.msg_queue.put(self._shutdown_sentinel)
183
+ if self.auto_update_thread:
184
+ self.auto_update_thread.join()
@@ -6,17 +6,16 @@ import json
6
6
  import os
7
7
  import select
8
8
  import subprocess
9
- import sys
10
9
  import threading
11
10
  import time
12
11
  import uuid
13
12
  from functools import wraps
14
13
  from typing import TYPE_CHECKING
15
14
 
15
+ from bec_lib.client import BECClient
16
16
  from bec_lib.endpoints import MessageEndpoints
17
17
  from bec_lib.logger import bec_logger
18
18
  from bec_lib.utils.import_utils import isinstance_based_on_class_name, lazy_import, lazy_import_from
19
- from qtpy.QtCore import QEventLoop, QSocketNotifier, QTimer
20
19
 
21
20
  import bec_widgets.cli.client as client
22
21
  from bec_widgets.cli.auto_updates import AutoUpdates
@@ -24,10 +23,6 @@ from bec_widgets.cli.auto_updates import AutoUpdates
24
23
  if TYPE_CHECKING:
25
24
  from bec_lib.device import DeviceBase
26
25
 
27
- from bec_widgets.cli.client import BECDockArea, BECFigure
28
-
29
- from bec_lib.serialization import MsgpackSerialization
30
-
31
26
  messages = lazy_import("bec_lib.messages")
32
27
  # from bec_lib.connector import MessageObject
33
28
  MessageObject = lazy_import_from("bec_lib.connector", ("MessageObject",))
@@ -184,7 +179,7 @@ class BECGuiClientMixin:
184
179
  if isinstance(msg, messages.ScanStatusMessage):
185
180
  if not self.gui_is_alive():
186
181
  return
187
- self.auto_updates.run(msg)
182
+ self.auto_updates.msg_queue.put(msg)
188
183
 
189
184
  def show(self) -> None:
190
185
  """
@@ -213,6 +208,8 @@ class BECGuiClientMixin:
213
208
  self._process_output_processing_thread.join()
214
209
  self._process.wait()
215
210
  self._process = None
211
+ if self.auto_updates is not None:
212
+ self.auto_updates.shutdown()
216
213
 
217
214
 
218
215
  class RPCResponseTimeoutError(Exception):
@@ -224,54 +221,14 @@ class RPCResponseTimeoutError(Exception):
224
221
  )
225
222
 
226
223
 
227
- class QtRedisMessageWaiter:
228
- def __init__(self, redis_connector, message_to_wait):
229
- self.ev_loop = QEventLoop()
230
- self.response = None
231
- self.connector = redis_connector
232
- self.message_to_wait = message_to_wait
233
- self.pubsub = redis_connector._redis_conn.pubsub()
234
- self.pubsub.subscribe(self.message_to_wait.endpoint)
235
- fd = self.pubsub.connection._sock.fileno()
236
- self.notifier = QSocketNotifier(fd, QSocketNotifier.Read)
237
- self.notifier.activated.connect(self._pubsub_readable)
238
-
239
- def _msg_received(self, msg_obj):
240
- self.response = msg_obj.value
241
- self.ev_loop.quit()
242
-
243
- def wait(self, timeout=1):
244
- timer = QTimer()
245
- timer.singleShot(timeout * 1000, self.ev_loop.quit)
246
- self.ev_loop.exec_()
247
- timer.stop()
248
- self.notifier.setEnabled(False)
249
- self.pubsub.close()
250
- return self.response
251
-
252
- def _pubsub_readable(self, fd):
253
- while True:
254
- msg = self.pubsub.get_message()
255
- if msg:
256
- if msg["type"] == "subscribe":
257
- # get_message buffers, so we may already have the answer
258
- # let's check...
259
- continue
260
- else:
261
- break
262
- else:
263
- return
264
- channel = msg["channel"].decode()
265
- msg = MessageObject(topic=channel, value=MsgpackSerialization.loads(msg["data"]))
266
- self.connector._execute_callback(self._msg_received, msg, {})
267
-
268
-
269
224
  class RPCBase:
270
225
  def __init__(self, gui_id: str = None, config: dict = None, parent=None) -> None:
271
- self._client = BECDispatcher().client
226
+ self._client = BECClient() # BECClient is a singleton; here, we simply get the instance
272
227
  self._config = config if config is not None else {}
273
228
  self._gui_id = gui_id if gui_id is not None else str(uuid.uuid4())
274
229
  self._parent = parent
230
+ self._msg_wait_event = threading.Event()
231
+ self._rpc_response = None
275
232
  super().__init__()
276
233
  # print(f"RPCBase: {self._gui_id}")
277
234
 
@@ -315,24 +272,39 @@ class RPCBase:
315
272
  # pylint: disable=protected-access
316
273
  receiver = self._root._gui_id
317
274
  if wait_for_rpc_response:
318
- redis_msg = QtRedisMessageWaiter(
319
- self._client.connector, MessageEndpoints.gui_instruction_response(request_id)
275
+ self._rpc_response = None
276
+ self._msg_wait_event.clear()
277
+ self._client.connector.register(
278
+ MessageEndpoints.gui_instruction_response(request_id),
279
+ cb=self._on_rpc_response,
280
+ parent=self,
320
281
  )
321
282
 
322
283
  self._client.connector.set_and_publish(MessageEndpoints.gui_instructions(receiver), rpc_msg)
323
284
 
324
285
  if wait_for_rpc_response:
325
- response = redis_msg.wait(timeout)
326
-
327
- if response is None:
328
- raise RPCResponseTimeoutError(request_id, timeout)
329
-
286
+ try:
287
+ finished = self._msg_wait_event.wait(10)
288
+ if not finished:
289
+ raise RPCResponseTimeoutError(request_id, timeout)
290
+ finally:
291
+ self._msg_wait_event.clear()
292
+ self._client.connector.unregister(
293
+ MessageEndpoints.gui_instruction_response(request_id), cb=self._on_rpc_response
294
+ )
330
295
  # get class name
331
- if not response.accepted:
332
- raise ValueError(response.message["error"])
333
- msg_result = response.message.get("result")
296
+ if not self._rpc_response.accepted:
297
+ raise ValueError(self._rpc_response.message["error"])
298
+ msg_result = self._rpc_response.message.get("result")
299
+ self._rpc_response = None
334
300
  return self._create_widget_from_msg_result(msg_result)
335
301
 
302
+ @staticmethod
303
+ def _on_rpc_response(msg: MessageObject, parent: RPCBase) -> None:
304
+ msg = msg.value
305
+ parent._msg_wait_event.set()
306
+ parent._rpc_response = msg
307
+
336
308
  def _create_widget_from_msg_result(self, msg_result):
337
309
  if msg_result is None:
338
310
  return None
@@ -0,0 +1,47 @@
1
+ from bec_lib.serialization import MsgpackSerialization
2
+ from bec_lib.utils import lazy_import_from
3
+ from qtpy.QtCore import QEventLoop, QSocketNotifier, QTimer
4
+
5
+ MessageObject = lazy_import_from("bec_lib.connector", ("MessageObject",))
6
+
7
+
8
+ class QtRedisMessageWaiter:
9
+ def __init__(self, redis_connector, message_to_wait):
10
+ self.ev_loop = QEventLoop()
11
+ self.response = None
12
+ self.connector = redis_connector
13
+ self.message_to_wait = message_to_wait
14
+ self.pubsub = redis_connector._redis_conn.pubsub()
15
+ self.pubsub.subscribe(self.message_to_wait.endpoint)
16
+ fd = self.pubsub.connection._sock.fileno()
17
+ self.notifier = QSocketNotifier(fd, QSocketNotifier.Read)
18
+ self.notifier.activated.connect(self._pubsub_readable)
19
+
20
+ def _msg_received(self, msg_obj):
21
+ self.response = msg_obj.value
22
+ self.ev_loop.quit()
23
+
24
+ def wait(self, timeout=1):
25
+ timer = QTimer()
26
+ timer.singleShot(timeout * 1000, self.ev_loop.quit)
27
+ self.ev_loop.exec_()
28
+ timer.stop()
29
+ self.notifier.setEnabled(False)
30
+ self.pubsub.close()
31
+ return self.response
32
+
33
+ def _pubsub_readable(self, fd):
34
+ while True:
35
+ msg = self.pubsub.get_message()
36
+ if msg:
37
+ if msg["type"] == "subscribe":
38
+ # get_message buffers, so we may already have the answer
39
+ # let's check...
40
+ continue
41
+ else:
42
+ break
43
+ else:
44
+ return
45
+ channel = msg["channel"].decode()
46
+ msg = MessageObject(topic=channel, value=MsgpackSerialization.loads(msg["data"]))
47
+ self.connector._execute_callback(self._msg_received, msg, {})
@@ -8,7 +8,7 @@ import redis
8
8
  from bec_lib.client import BECClient
9
9
  from bec_lib.redis_connector import MessageObject, RedisConnector
10
10
  from bec_lib.service_config import ServiceConfig
11
- from qtpy.QtCore import PYQT6, PYSIDE6, QCoreApplication, QObject
11
+ from qtpy.QtCore import QObject
12
12
  from qtpy.QtCore import Signal as pyqtSignal
13
13
 
14
14
  if TYPE_CHECKING:
@@ -75,7 +75,6 @@ class BECDispatcher:
75
75
 
76
76
  _instance = None
77
77
  _initialized = False
78
- qapp = None
79
78
 
80
79
  def __new__(cls, client=None, config: str = None, *args, **kwargs):
81
80
  if cls._instance is None:
@@ -87,9 +86,6 @@ class BECDispatcher:
87
86
  if self._initialized:
88
87
  return
89
88
 
90
- if not QCoreApplication.instance():
91
- BECDispatcher.qapp = QCoreApplication([])
92
-
93
89
  self._slots = collections.defaultdict(set)
94
90
  self.client = client
95
91
 
@@ -123,16 +119,6 @@ class BECDispatcher:
123
119
  cls._instance = None
124
120
  cls._initialized = False
125
121
 
126
- if not cls.qapp:
127
- return
128
-
129
- # shutdown QCoreApp if it exists
130
- if PYQT6:
131
- cls.qapp.exit()
132
- elif PYSIDE6:
133
- cls.qapp.shutdown()
134
- cls.qapp = None
135
-
136
122
  def connect_slot(
137
123
  self,
138
124
  slot: Callable,
@@ -457,7 +457,6 @@ class BECImageWidget(BECWidget, QWidget):
457
457
 
458
458
  def cleanup(self):
459
459
  self.fig.cleanup()
460
- self.client.shutdown()
461
460
  self.toolbar.close()
462
461
  self.toolbar.deleteLater()
463
462
  return super().cleanup()
@@ -63,8 +63,6 @@ class BECJupyterConsole(RichJupyterWidget): # pragma: no cover:
63
63
 
64
64
  def closeEvent(self, event):
65
65
  self.shutdown_kernel()
66
- if self.client:
67
- self.client.shutdown()
68
66
 
69
67
 
70
68
  if __name__ == "__main__": # pragma: no cover
@@ -561,7 +561,6 @@ class BECWaveformWidget(BECWidget, QWidget):
561
561
 
562
562
  def cleanup(self):
563
563
  self.fig.cleanup()
564
- self.client.shutdown()
565
564
  return super().cleanup()
566
565
 
567
566
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.94.3
3
+ Version: 0.94.5
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
@@ -9,8 +9,8 @@ Classifier: Development Status :: 3 - Alpha
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Topic :: Scientific/Engineering
11
11
  Requires-Python: >=3.10
12
- Requires-Dist: bec-ipython-client~=2.16
13
- Requires-Dist: bec-lib~=2.16
12
+ Requires-Dist: bec-ipython-client>=2.21.4,~=2.21
13
+ Requires-Dist: bec-lib>=2.21.4,~=2.21
14
14
  Requires-Dist: bec-qthemes~=0.0
15
15
  Requires-Dist: black~=24.0
16
16
  Requires-Dist: isort>=5.13.2,~=5.13
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=BtKhZI3dhK09En1BfpglYi-ZJwG6ZdC-iJr7kXFVfCg,8346
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=gE46tUW66TsIdZamfkYZMGj7-k6WJUT4oPY_7PPyQ3Q,6445
5
+ CHANGELOG.md,sha256=AyMvWke1tWeCvkvs9EWcNaIC75E7qlOfzgBNyQGO1ks,6719
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=giIQGgT_Zow6YiayO_MJDB6XtuM2IEnWABhbbg14HrA,1307
7
+ PKG-INFO,sha256=R5qONexTNA-N-SUHcQY1xSlCgOesmiI9osI0vnQIMec,1325
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=7CgY9VSUC5P1rXOXpjUppxnvxkVqsajIgSZQefR2-iA,2356
9
+ pyproject.toml,sha256=32PfrgJSI6hyIzuMrPw4QtjsWpuLjvKkEZmQhMpR7ms,2416
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
@@ -81,9 +81,9 @@ bec_widgets/assets/toolbar_icons/terminal.svg,sha256=jV0cHThRmM1eXm3ETEWfSkEz8AX
81
81
  bec_widgets/assets/toolbar_icons/transform.svg,sha256=Fgug9wCi1FONy08nssEvnoDDDBbSrlNPu_pBF85GzgY,518
82
82
  bec_widgets/assets/toolbar_icons/waveform.svg,sha256=darXWaIww4HEu9skFUd8Vs1NSAgUo1d37xBNr6DX-bM,231
83
83
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
84
- bec_widgets/cli/auto_updates.py,sha256=DyBV3HnjMSH-cvVkYNcDiYKVf0Xut4Qy2qGQqkW47Bw,4833
84
+ bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
85
85
  bec_widgets/cli/client.py,sha256=HjBxjthimBvbyVrjvLZoeBN1NdezupowRYjZxqDlOX8,76261
86
- bec_widgets/cli/client_utils.py,sha256=cDhabblwaP88a0jlVpbn_RWWKVbsyjhmmGtMh9gesEw,12388
86
+ bec_widgets/cli/client_utils.py,sha256=isk0bUcubdbqzIstN3peQpjV9pLuNUBZsHlIedIhCCw,11594
87
87
  bec_widgets/cli/generate_cli.py,sha256=Ea5px9KblUlcGg-1JbJBTIU7laGg2n8PM7Efw9WVVzM,5889
88
88
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
89
89
  bec_widgets/cli/rpc_wigdet_handler.py,sha256=6kQng2DyS6rhLJqSJ7xa0kdgSxp-35A2upcf833dJRE,1483
@@ -104,12 +104,13 @@ bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py,sha256=Hj-04Y3u_0H
104
104
  bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-60zjQ2FAs88Ldjm1MfoMROfiQZZu6Guav8,2379
105
105
  bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
106
  bec_widgets/qt_utils/error_popups.py,sha256=y9gKKWaafp468ioHr96nBhf02ZpEgjDc-BAVOTWh-e8,7680
107
+ bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
107
108
  bec_widgets/qt_utils/settings_dialog.py,sha256=NhtzTer_xzlB2lLLrGklkI1QYLJEWQpJoZbCz4o5daI,3645
108
109
  bec_widgets/qt_utils/toolbar.py,sha256=89WddOXPePby2CICUumdN_K_3DBgZPCR8HWUJAwrhDU,6503
109
110
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
110
111
  bec_widgets/utils/bec_connector.py,sha256=SivHKXVyNVqeu3kCXYEPpbleTVw8g1cW0FKq1QrQgco,9987
111
112
  bec_widgets/utils/bec_designer.py,sha256=ak3G8FdojUPjVBBwdPXw7tN5P2Uxr-SSoQt394jXeAA,4308
112
- bec_widgets/utils/bec_dispatcher.py,sha256=l2NRuiHGA-tr3gwJXSk7h5ZBKDuDqP8gmJKHJFc_n9I,6225
113
+ bec_widgets/utils/bec_dispatcher.py,sha256=F66edY3Ib_ZjTT24qoAbjwUOdOKt6CiWUUqN1I1xxZs,5865
113
114
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
114
115
  bec_widgets/utils/bec_widget.py,sha256=Bo2v1aP7rgSAQajW8GBJbI3iovTn_hGCsmeFMo7bT10,707
115
116
  bec_widgets/utils/colors.py,sha256=hNIi99EpMv3t3hTJIL2jBe5nzh5f2fuCyEKXEPWSQSc,10501
@@ -187,10 +188,10 @@ bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=ZwRxSfPHbMWEv
187
188
  bec_widgets/widgets/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
189
  bec_widgets/widgets/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
189
190
  bec_widgets/widgets/image/bec_image_widget_plugin.py,sha256=B7whBMsoQ85MyCR_C6YHBl2s1T7odOJJYeiHaLXzmcM,1387
190
- bec_widgets/widgets/image/image_widget.py,sha256=csPtl48uZgSlyomxG68bFJX929Y2WOvgv5risWQuXFI,16319
191
+ bec_widgets/widgets/image/image_widget.py,sha256=TCpTF8v94iSMklG9bYxZOjm9SbO60XZB9X0ldEp8lWE,16288
191
192
  bec_widgets/widgets/image/register_bec_image_widget.py,sha256=01YLZQTMSSIXvH1TSL-1AYsRs1a4EbSwKLVAwh9AjeA,478
192
193
  bec_widgets/widgets/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
193
- bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=mBKM89H6SuHuFy1lQg1n8s1gQiN5QEkZf0xua8aPDns,2402
194
+ bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=-e7HQOECeH5eDrJYh4BFIzRL78LDkooU4otabyN0aX4,2343
194
195
  bec_widgets/widgets/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
196
  bec_widgets/widgets/motor_map/bec_motor_map_widget.pyproject,sha256=NAI8s5gRKz80ED4KY7OgD2OgSH5HEsjt2ux2BYp66yg,63
196
197
  bec_widgets/widgets/motor_map/bec_motor_map_widget_plugin.py,sha256=V6iN82E8Za8BharR_cSyZZShh4fI9yc5ky2TQBGELR0,1316
@@ -256,7 +257,7 @@ bec_widgets/widgets/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
256
257
  bec_widgets/widgets/waveform/bec_waveform_widget.pyproject,sha256=GLD8GN9dXx9wNbtnevrxqqcwk7vKV-Uv8QYSycdaoaI,33
257
258
  bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py,sha256=D9q3wdBPB5x0iCzyYDo1qdSXzySXdRIc1d5oD3Gv5gY,1420
258
259
  bec_widgets/widgets/waveform/register_bec_waveform_widget.py,sha256=qZHVZH_lP2hvzkG1Ra0EyrXlMeLkRCy0aceH-bfJ1cs,490
259
- bec_widgets/widgets/waveform/waveform_widget.py,sha256=zErnkgwm69QZEVvNRLi57v9-zRQeu0IaJpYRj34mGmA,19125
260
+ bec_widgets/widgets/waveform/waveform_widget.py,sha256=4aHwkLdn7C8BgvKqFIbOB0YaAxAIIFTG_hG0iLougKQ,19094
260
261
  bec_widgets/widgets/waveform/waveform_popups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
262
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
263
  bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py,sha256=S1j44i1xxJtmCcNtbOsxF8XdklMPsG9t4-1DZ2YfOPw,13128
@@ -285,10 +286,11 @@ docs/assets/index_contribute.svg,sha256=OCjvYBw_JhcY_D5Zd7f1MctQvq1YNalYlqPNwB1X
285
286
  docs/assets/index_getting_started.svg,sha256=Www1OXmauYlouZD51AR6-VG2vxrEig8-jjuDPhzkNxc,3977
286
287
  docs/assets/index_user_guide.svg,sha256=sRjKwOHVJStBYIQUFVcnfmbeXd2qAp0HYjleSp66XCI,6429
287
288
  docs/assets/rocket_launch_48dp.svg,sha256=pdrPrBcKWUa5OlgWKM0B6TA6qAW7E57d7C7YW2r1OT8,1070
288
- docs/developer/developer.md,sha256=VUdMnQBsSRCawYMFCe0vya5oj1MimLML7Pd58kY6fYY,765
289
- docs/developer/getting_started/development.md,sha256=aYLmuLMYpp5FcIXeDUqCfcStIV8veuiMBjOt5bTW_30,1406
290
- docs/developer/getting_started/getting_started.md,sha256=My_K_6O7LLaXVB_eINrRku5o-jVx95lsmGgHxgZhT7A,378
291
- docs/developer/widgets/widgets.md,sha256=aNsJgG7R-3EerumNB6GH84JLIXfZqGN5GjvpKWDi0Hk,504
289
+ docs/developer/developer.md,sha256=LUbV1dnVI9r8FhsL2htKRqrGZDGkFXA-jo5TJfXz4OI,1099
290
+ docs/developer/introduction/concepts.md,sha256=N23ewZjPx97eJtrU6-0Lou2IvPfkfZ6Nw6n9SwASQ74,1721
291
+ docs/developer/introduction/contributing.md,sha256=ocW5kjBNwD5k_nDkusXUpsW8jJALajrpNSRVJftuF-k,1668
292
+ docs/developer/introduction/introduction.md,sha256=860Sw05t1RGW13IUlM5bJwK8DckYhSABPKZykgmwcpA,774
293
+ docs/developer/widget_development/widget_development.md,sha256=wGfDjbt9EonVxUg59keADy7wCLyS-KzCz7m4hY0OV_A,526
292
294
  docs/introduction/introduction.md,sha256=YBEFDhxqHTcbfbNTo76xDflaFUHIqDs-sToA1HRmCnI,1436
293
295
  docs/user/customisation.md,sha256=wCW8fAbqtlgGE3mURvXOrK67Xo0_B-lxfg0sYuQWB40,3186
294
296
  docs/user/user.md,sha256=uCTcjclIi6rdjYRQebko6bWFEVsjyfshsVU3BDYrC-Y,1403
@@ -321,7 +323,7 @@ docs/user/widgets/widgets.md,sha256=ZeRNmP7GUOu8kEoGu9XHsyF8Hb1foqZKEbwpgFP7ITk,
321
323
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
322
324
  tests/end-2-end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
325
  tests/end-2-end/conftest.py,sha256=-BLnFE-NeCerf6xahGCkbZ4Ktactowi6RkBnboIzRvg,1767
324
- tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=FwbqHOlEcdimTiJaOJKfqHkOhqJY6R8Z9YNYnU8QCt4,9447
326
+ tests/end-2-end/test_bec_dock_rpc_e2e.py,sha256=jC-FjsmL7ZOy_a8zojyhbzsOLgpWC6PNogQ2_gxCO5I,9480
325
327
  tests/end-2-end/test_bec_figure_rpc_e2e.py,sha256=_OTyZfkF0D9cvdwRhHNfNadCpZPWybOCryN6EUs7tXI,6804
326
328
  tests/end-2-end/test_rpc_register_e2e.py,sha256=blhMiW7HVHX1kGm5dg8Sv0PeCuJ0gnBz3evznQFz_B8,1619
327
329
  tests/end-2-end/test_scan_control_e2e.py,sha256=u7oLgFyltkMW2apSZKDukMIXvYrbhHrU32p4mBdn8VE,2276
@@ -376,8 +378,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
376
378
  tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
377
379
  tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
378
380
  tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
379
- bec_widgets-0.94.3.dist-info/METADATA,sha256=giIQGgT_Zow6YiayO_MJDB6XtuM2IEnWABhbbg14HrA,1307
380
- bec_widgets-0.94.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
381
- bec_widgets-0.94.3.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
382
- bec_widgets-0.94.3.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
383
- bec_widgets-0.94.3.dist-info/RECORD,,
381
+ bec_widgets-0.94.5.dist-info/METADATA,sha256=R5qONexTNA-N-SUHcQY1xSlCgOesmiI9osI0vnQIMec,1325
382
+ bec_widgets-0.94.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
383
+ bec_widgets-0.94.5.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
384
+ bec_widgets-0.94.5.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
385
+ bec_widgets-0.94.5.dist-info/RECORD,,
@@ -1,7 +1,9 @@
1
1
  (developer)=
2
2
  # Developer
3
3
 
4
- Welcome to the BEC Widgets developer guide! This section is intended for developers who want to contribute to the development of BEC Widgets.
4
+ Welcome to the BEC Widgets developer guide! BEC Widgets is a framework for building graphical user interfaces (GUIs) for [BEC](https://bec.readthedocs.io/en/latest/), a Python package for beamline experiment control.
5
+
6
+ This guide targets readers who want to develop new widgets or extend existing ones. If your goal is to use BEC Widgets to build GUIs for your experiments, please refer to the [user guide](#user).
5
7
 
6
8
  ```{toctree}
7
9
  ---
@@ -9,8 +11,8 @@ maxdepth: 2
9
11
  hidden: true
10
12
  ---
11
13
 
12
- getting_started/getting_started.md
13
- widgets/widgets.md
14
+ introduction/introduction.md
15
+ widget_development/widget_development.md
14
16
  api_reference/api_reference.md
15
17
  ```
16
18
 
@@ -21,26 +23,28 @@ api_reference/api_reference.md
21
23
  :gutter: 5
22
24
 
23
25
  ```{grid-item-card}
24
- :link: developer.getting_started
26
+ :link: developer.introduction
25
27
  :link-type: ref
26
28
  :img-top: /assets/rocket_launch_48dp.svg
27
29
  :text-align: center
28
30
 
29
- ## Getting Started
31
+ ## Introduction
30
32
 
31
- Learn how to install BEC Widgets and get started with the framework.
33
+ An introduction into the single-resposibility principle and the modular design of BEC Widgets.
32
34
  ```
33
35
 
34
36
  ```{grid-item-card}
35
- :link: developer.widgets
37
+ :link: developer.widget_development
36
38
  :link-type: ref
37
39
  :img-top: /assets/apps_48dp.svg
38
40
  :text-align: center
39
41
 
40
- ## Widgets
42
+ ## Widget Development
41
43
 
42
- Learn about the building blocks of larger applications: widgets.
44
+ Learn how to develop a new modular widget for BEC Widgets.
43
45
  ```
44
- ````
46
+
47
+ ````{grid} 2
48
+
45
49
 
46
50
 
@@ -0,0 +1,14 @@
1
+ (developer.concepts)=
2
+ # Concepts
3
+ This section provides an overview of the core concepts of BEC Widgets, which are based on the single-responsibility principle and modular design.
4
+
5
+ ## Moduler Design
6
+ We develop widgets with the single-responsibility principle in mind, meaning each widget is designed for a specific task. Our goal is to keep widgets simple, using them primarily for visualization or to initiate actions within BEC. Following these ideas, widgets should be designed to be reusable in various applications, making them versatile building blocks for larger GUIs.
7
+
8
+ We offer up to three different options for composing larger GUIs from these modular widgets: BECDesigner, DockArea widget, or scripting from the command line interface. More information about these options can be found in the user sections on [applications](user.applications).
9
+
10
+ ## Client-Server Architecture
11
+
12
+ BEC Widgets is built on top of the [BEC](https://bec.readthedocs.io/en/latest/) package, which provides the backend for beamline experiment control. BEC Widgets is a client of BEC, meaning it can interact with the backend through a client-server architecture. To make full usage of the available features of BEC, we recommend to check the documentation about [data access](https://bec.readthedocs.io/en/latest/developer/data_access/data_access.html) in which the messaging and event system of BEC is described.
13
+ In the context of BEC Widgets, the [`BECDispatcher`](/api_reference/_autosummary/bec_widgets.utils.bec_dispatcher.BECDispatcher) connects to this messaging and event system, allowing you to link your Qt [`Slots`](https://www.pythonguis.com/tutorials/pyside6-signals-slots-events/) to messages and event received from BEC.
14
+
@@ -1,5 +1,5 @@
1
- (developer.development)=
2
- # Development
1
+ (developer.contributing)=
2
+ # Contributing
3
3
 
4
4
  If you like to contribute to the development of BEC Widgets, you can follow the steps below to set up your development environment.
5
5
  BEC Widgets works in conjunction with [BEC](https://bec.readthedocs.io/en/latest/).
@@ -10,6 +10,7 @@ If you already have a BEC environment set up, you can install BEC Widgets in edi
10
10
  **Prerequisites**
11
11
  1. **Python Version:** BEC Widgets requires Python version 3.10 or higher. Verify your Python version to ensure compatibility.
12
12
  2. **BEC Installation:** BEC Widgets works in conjunction with BEC. While BEC is a dependency and will be installed automatically, you can find more information about BEC and its installation process in the [BEC documentation](https://beamline-experiment-control.readthedocs.io/en/latest/).
13
+ 3. **Qt Distributions:** BEC Widgets supports [PySide6](https://doc.qt.io/qtforpython-6/quickstart.html) and [PyQt6](https://www.riverbankcomputing.com/static/Docs/PyQt6/introduction.html). We use [qtpy](https://pypi.org/project/QtPy/) to abstract the underlying QT distribution.
13
14
 
14
15
  **Clone the Repository**:
15
16
  ```bash
@@ -20,8 +21,8 @@ cd bec_widgets
20
21
 
21
22
  Please install the package in editable mode into your BEC Python environemnt.
22
23
  ```bash
23
- pip install -e '.[dev,pyqt6]'
24
+ pip install -e '.[dev,pyside6]'
24
25
  ```
25
- This installs the package together with [PyQT6](https://www.riverbankcomputing.com/static/Docs/PyQt6/introduction.html).
26
+ This installs the package together with [PySide6](https://doc.qt.io/qtforpython-6/quickstart.html).
26
27
 
27
28
 
@@ -0,0 +1,15 @@
1
+ (developer.introduction)=
2
+ # Introduction
3
+ BEC Widgets is a framework providing modular components that can be integrated into various larger GUI applications. Each widget serves a specific purpose adhering to the single-responsibility principle as detailed in our [concepts section](developer.concepts), and offers a straightforward, user-friendly interface.
4
+ These widgets provide data visualisation tools and experimental control interfaces by triggering actions within BEC.
5
+ If you're interested in contributing to BEC Widgets, please refer to our [contributing guide](developer.contributing), which provides instructions for setting up your development environment and creating your own widgets.
6
+
7
+ ```{toctree}
8
+ ---
9
+ maxdepth: 2
10
+ hidden: false
11
+ ---
12
+
13
+ concepts/
14
+ contributing/
15
+ ```
@@ -1,5 +1,5 @@
1
- (developer.widgets)=
2
- # Widgets
1
+ (developer.widget_development)=
2
+ # Widget development
3
3
  This section provides an introduction to the building blocks of BEC Widgets: widgets. Widgets are the basic components of the graphical user interface (GUI) and are used to create larger applications. We will cover key topics such as how to develop new widgets or how to customise existing widgets. For details on the already available widgets and their usage, please refer to user section about [widgets](#user.widgets)
4
4
 
5
5
  ```{toctree}
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.94.3"
7
+ version = "0.94.5"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -13,16 +13,16 @@ classifiers = [
13
13
  "Topic :: Scientific/Engineering",
14
14
  ]
15
15
  dependencies = [
16
- "bec_ipython_client~=2.16", # needed for jupyter console
17
- "bec_lib~=2.16",
18
- "black~=24.0", # needed for bw-generate-cli
19
- "isort~=5.13, >=5.13.2", # needed for bw-generate-cli
16
+ "bec_ipython_client~=2.21, >=2.21.4", # needed for jupyter console
17
+ "bec_lib~=2.21, >=2.21.4",
18
+ "black~=24.0", # needed for bw-generate-cli
19
+ "isort~=5.13, >=5.13.2", # needed for bw-generate-cli
20
20
  "pydantic~=2.0",
21
21
  "pyqtgraph~=0.13",
22
22
  "bec_qthemes~=0.0",
23
- "qtconsole~=5.5, >=5.5.1", # needed for jupyter console
23
+ "qtconsole~=5.5, >=5.5.1", # needed for jupyter console
24
24
  "qtpy~=2.4",
25
- "pyte", # needed for vt100 console
25
+ "pyte", # needed for vt100 console
26
26
  ]
27
27
 
28
28
 
@@ -295,3 +295,4 @@ def test_auto_update(bec_client_lib, rpc_server_dock, qtbot):
295
295
  plt_data[f"Scan {status.scan.scan_number} - {dock.selected_device}"]["y"]
296
296
  == last_scan_data["samy"]["samy"].val
297
297
  )
298
+ dock.auto_updates.shutdown()
@@ -1,12 +0,0 @@
1
- (developer.getting_started)=
2
- # Getting Started
3
- This section provides valuable information for developers who want to contribute to the development of BEC Widgets. The guide will help you set up the development environment, understand the modular development concept of BEC Widgets, and contribute to the project.
4
-
5
- ```{toctree}
6
- ---
7
- maxdepth: 2
8
- hidden: false
9
- ---
10
-
11
- development/
12
- ```