bec-widgets 0.66.1__py3-none-any.whl → 0.68.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 +42 -40
- PKG-INFO +1 -1
- bec_widgets/cli/client.py +82 -3
- bec_widgets/cli/client_utils.py +46 -34
- bec_widgets/cli/server.py +61 -18
- bec_widgets/utils/bec_dispatcher.py +14 -6
- bec_widgets/widgets/bec_status_box/__init__.py +0 -0
- bec_widgets/widgets/bec_status_box/bec_status_box.py +352 -0
- bec_widgets/widgets/bec_status_box/status_item.py +171 -0
- {bec_widgets-0.66.1.dist-info → bec_widgets-0.68.0.dist-info}/METADATA +1 -1
- {bec_widgets-0.66.1.dist-info → bec_widgets-0.68.0.dist-info}/RECORD +24 -18
- docs/developer/widgets/widgets.md +0 -1
- docs/requirements.txt +1 -0
- docs/user/getting_started/installation.md +2 -2
- docs/user/widgets/bec_status_box.gif +0 -0
- docs/user/widgets/bec_status_box.md +30 -0
- docs/user/widgets/buttons.md +0 -1
- docs/user/widgets/widgets.md +2 -0
- pyproject.toml +1 -1
- tests/end-2-end/conftest.py +1 -4
- tests/unit_tests/test_bec_status_box.py +152 -0
- {bec_widgets-0.66.1.dist-info → bec_widgets-0.68.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.66.1.dist-info → bec_widgets-0.68.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.66.1.dist-info → bec_widgets-0.68.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,5 +1,47 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v0.68.0 (2024-06-21)
|
4
|
+
|
5
|
+
### Feature
|
6
|
+
|
7
|
+
* feat: properly handle SIGINT (ctrl-c) in BEC GUI server -> calls qapplication.quit() ([`3644f34`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3644f344da2df674bc0d5740c376a86b9d0dfe95))
|
8
|
+
|
9
|
+
* feat: bec-gui-server: redirect stdout and stderr (if any) as proper debug and error log entries ([`d1266a1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d1266a1ce148ff89557a039e3a182a87a3948f49))
|
10
|
+
|
11
|
+
* feat: add logger for BEC GUI server ([`630616e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/630616ec729f60aa0b4d17a9e0379f9c6198eb96))
|
12
|
+
|
13
|
+
### Fix
|
14
|
+
|
15
|
+
* fix: ignore GUI server output (any output will go to log file)
|
16
|
+
|
17
|
+
If a logger is given to log `_start_log_process`, the server stdout and
|
18
|
+
stderr streams will be redirected as log entries with levels DEBUG or ERROR
|
19
|
+
in their parent process ([`ce37416`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ce374163cab87a92847409051739777bc505a77b))
|
20
|
+
|
21
|
+
* fix: do not create 'BECClient' logger when instantiating BECDispatcher ([`f7d0b07`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f7d0b0768ace42a33e2556bb33611d4f02e5a6d9))
|
22
|
+
|
23
|
+
## v0.67.0 (2024-06-21)
|
24
|
+
|
25
|
+
### Documentation
|
26
|
+
|
27
|
+
* docs: add widget to documentation ([`6fa1c06`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6fa1c06053131dabd084bb3cf13c853b5d3ce833))
|
28
|
+
|
29
|
+
### Feature
|
30
|
+
|
31
|
+
* feat: introduce BECStatusBox Widget ([`443b6c1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/443b6c1d7b02c772fda02e2d1eefd5bd40249e0c))
|
32
|
+
|
33
|
+
### Refactor
|
34
|
+
|
35
|
+
* refactor: Change inheritance to QTreeWidget from QWidget ([`d2f2b20`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d2f2b206bb0eab60b8a9b0d0ac60a6b7887fa6fb))
|
36
|
+
|
37
|
+
### Test
|
38
|
+
|
39
|
+
* test: add test suite for bec_status_box and status_item ([`5d4ca81`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5d4ca816cdedec4c88aba9eb326f85392504ea1c))
|
40
|
+
|
41
|
+
### Unknown
|
42
|
+
|
43
|
+
* Update file requirements.txt ([`505a5ec`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/505a5ec8334ff4422913b3a7b79d39bcb42ad535))
|
44
|
+
|
3
45
|
## v0.66.1 (2024-06-20)
|
4
46
|
|
5
47
|
### Fix
|
@@ -133,46 +175,6 @@ This reverts commit abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3 ([`fe04dd8`](https:
|
|
133
175
|
|
134
176
|
## v0.62.0 (2024-06-12)
|
135
177
|
|
136
|
-
### Feature
|
137
|
-
|
138
|
-
* feat: implement non-polling, interruptible waiting of gui instruction response with timeout ([`abc6caa`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3))
|
139
|
-
|
140
178
|
### Unknown
|
141
179
|
|
142
180
|
* doc: add documentation about creating custom GUI applications embedding BEC Widgets ([`17a0068`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/17a00687579f5efab1990cd83862ec0e78198633))
|
143
|
-
|
144
|
-
## v0.61.0 (2024-06-12)
|
145
|
-
|
146
|
-
### Feature
|
147
|
-
|
148
|
-
* feat(widgets/stop_button): General stop button added ([`61ba08d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/61ba08d0b8df9f48f5c54c7c2b4e6d395206e7e6))
|
149
|
-
|
150
|
-
### Refactor
|
151
|
-
|
152
|
-
* refactor: improve labe of auto_update script ([`40b5688`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/40b568815893cd41af3531bb2e647ca1e2e315f4))
|
153
|
-
|
154
|
-
## v0.60.0 (2024-06-08)
|
155
|
-
|
156
|
-
### Ci
|
157
|
-
|
158
|
-
* ci: added git fetch for target branch ([`fc4f4f8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fc4f4f81ad1be99cf5112f2188a46c5bed2679ee))
|
159
|
-
|
160
|
-
* ci: fixed pylint-check ([`6b1d582`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6b1d5827d6599f06a3acd316060a8d25f0686d54))
|
161
|
-
|
162
|
-
### Feature
|
163
|
-
|
164
|
-
* feat: added isort to bw-generate-cli ([`f0391f5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f0391f59c9eb0a51b693fccfe2e399e869d35dda))
|
165
|
-
|
166
|
-
### Fix
|
167
|
-
|
168
|
-
* fix: removed BECConnector from rpc client interface ([`6428e38`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6428e38ab94c15a2c904e75cc6404bb6d0394e04))
|
169
|
-
|
170
|
-
### Refactor
|
171
|
-
|
172
|
-
* refactor: minor cleanup ([`3adf6cf`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3adf6cfd586355c8b8ce7fdc9722f868e22287c5))
|
173
|
-
|
174
|
-
* refactor: disabled pylint for auto-gen client ([`b15816c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b15816ca9fd3e4ae87cca5fcfe029b4dfca570ca))
|
175
|
-
|
176
|
-
### Test
|
177
|
-
|
178
|
-
* test: added missing pylint statement to header ([`f662985`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f6629852ebc2b4ee239fa560cc310a5ae2627cf7))
|
PKG-INFO
CHANGED
bec_widgets/cli/client.py
CHANGED
@@ -13,6 +13,7 @@ class Widgets(str, enum.Enum):
|
|
13
13
|
Enum for the available widgets.
|
14
14
|
"""
|
15
15
|
|
16
|
+
BECStatusBox = "BECStatusBox"
|
16
17
|
BECDock = "BECDock"
|
17
18
|
BECDockArea = "BECDockArea"
|
18
19
|
BECFigure = "BECFigure"
|
@@ -1388,6 +1389,24 @@ class BECPlotBase(RPCBase):
|
|
1388
1389
|
"""
|
1389
1390
|
|
1390
1391
|
|
1392
|
+
class BECStatusBox(RPCBase):
|
1393
|
+
@property
|
1394
|
+
@rpc_call
|
1395
|
+
def config_dict(self) -> "dict":
|
1396
|
+
"""
|
1397
|
+
Get the configuration of the widget.
|
1398
|
+
|
1399
|
+
Returns:
|
1400
|
+
dict: The configuration of the widget.
|
1401
|
+
"""
|
1402
|
+
|
1403
|
+
@rpc_call
|
1404
|
+
def get_all_rpc(self) -> "dict":
|
1405
|
+
"""
|
1406
|
+
Get all registered RPC objects.
|
1407
|
+
"""
|
1408
|
+
|
1409
|
+
|
1391
1410
|
class BECWaveform(RPCBase):
|
1392
1411
|
@property
|
1393
1412
|
@rpc_call
|
@@ -1649,6 +1668,60 @@ class BECWaveform(RPCBase):
|
|
1649
1668
|
"""
|
1650
1669
|
|
1651
1670
|
|
1671
|
+
class DeviceComboBox(RPCBase):
|
1672
|
+
@property
|
1673
|
+
@rpc_call
|
1674
|
+
def config_dict(self) -> "dict":
|
1675
|
+
"""
|
1676
|
+
Get the configuration of the widget.
|
1677
|
+
|
1678
|
+
Returns:
|
1679
|
+
dict: The configuration of the widget.
|
1680
|
+
"""
|
1681
|
+
|
1682
|
+
@rpc_call
|
1683
|
+
def get_all_rpc(self) -> "dict":
|
1684
|
+
"""
|
1685
|
+
Get all registered RPC objects.
|
1686
|
+
"""
|
1687
|
+
|
1688
|
+
|
1689
|
+
class DeviceInputBase(RPCBase):
|
1690
|
+
@property
|
1691
|
+
@rpc_call
|
1692
|
+
def config_dict(self) -> "dict":
|
1693
|
+
"""
|
1694
|
+
Get the configuration of the widget.
|
1695
|
+
|
1696
|
+
Returns:
|
1697
|
+
dict: The configuration of the widget.
|
1698
|
+
"""
|
1699
|
+
|
1700
|
+
@rpc_call
|
1701
|
+
def get_all_rpc(self) -> "dict":
|
1702
|
+
"""
|
1703
|
+
Get all registered RPC objects.
|
1704
|
+
"""
|
1705
|
+
|
1706
|
+
|
1707
|
+
class DeviceLineEdit(RPCBase):
|
1708
|
+
@property
|
1709
|
+
@rpc_call
|
1710
|
+
def config_dict(self) -> "dict":
|
1711
|
+
"""
|
1712
|
+
Get the configuration of the widget.
|
1713
|
+
|
1714
|
+
Returns:
|
1715
|
+
dict: The configuration of the widget.
|
1716
|
+
"""
|
1717
|
+
|
1718
|
+
@rpc_call
|
1719
|
+
def get_all_rpc(self) -> "dict":
|
1720
|
+
"""
|
1721
|
+
Get all registered RPC objects.
|
1722
|
+
"""
|
1723
|
+
|
1724
|
+
|
1652
1725
|
class Ring(RPCBase):
|
1653
1726
|
@rpc_call
|
1654
1727
|
def get_all_rpc(self) -> "dict":
|
@@ -1950,7 +2023,7 @@ class TextBox(RPCBase):
|
|
1950
2023
|
@rpc_call
|
1951
2024
|
def set_color(self, background_color: str, font_color: str) -> None:
|
1952
2025
|
"""
|
1953
|
-
Set the background color of the
|
2026
|
+
Set the background color of the widget.
|
1954
2027
|
|
1955
2028
|
Args:
|
1956
2029
|
background_color (str): The color to set the background in HEX.
|
@@ -1960,13 +2033,19 @@ class TextBox(RPCBase):
|
|
1960
2033
|
@rpc_call
|
1961
2034
|
def set_text(self, text: str) -> None:
|
1962
2035
|
"""
|
1963
|
-
Set the text of the
|
2036
|
+
Set the text of the widget.
|
2037
|
+
|
2038
|
+
Args:
|
2039
|
+
text (str): The text to set.
|
1964
2040
|
"""
|
1965
2041
|
|
1966
2042
|
@rpc_call
|
1967
2043
|
def set_font_size(self, size: int) -> None:
|
1968
2044
|
"""
|
1969
|
-
Set the font size of the text in the
|
2045
|
+
Set the font size of the text in the widget.
|
2046
|
+
|
2047
|
+
Args:
|
2048
|
+
size (int): The font size to set.
|
1970
2049
|
"""
|
1971
2050
|
|
1972
2051
|
|
bec_widgets/cli/client_utils.py
CHANGED
@@ -13,6 +13,7 @@ from functools import wraps
|
|
13
13
|
from typing import TYPE_CHECKING
|
14
14
|
|
15
15
|
from bec_lib.endpoints import MessageEndpoints
|
16
|
+
from bec_lib.logger import bec_logger
|
16
17
|
from bec_lib.utils.import_utils import isinstance_based_on_class_name, lazy_import, lazy_import_from
|
17
18
|
from qtpy.QtCore import QEventLoop, QSocketNotifier, QTimer
|
18
19
|
|
@@ -31,6 +32,8 @@ messages = lazy_import("bec_lib.messages")
|
|
31
32
|
MessageObject = lazy_import_from("bec_lib.connector", ("MessageObject",))
|
32
33
|
BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",))
|
33
34
|
|
35
|
+
logger = bec_logger.logger
|
36
|
+
|
34
37
|
|
35
38
|
def rpc_call(func):
|
36
39
|
"""
|
@@ -63,45 +66,64 @@ def rpc_call(func):
|
|
63
66
|
return wrapper
|
64
67
|
|
65
68
|
|
66
|
-
def _get_output(process) -> None:
|
69
|
+
def _get_output(process, logger) -> None:
|
70
|
+
log_func = {process.stdout: logger.debug, process.stderr: logger.error}
|
71
|
+
stream_buffer = {process.stdout: [], process.stderr: []}
|
67
72
|
try:
|
68
73
|
os.set_blocking(process.stdout.fileno(), False)
|
69
74
|
os.set_blocking(process.stderr.fileno(), False)
|
70
75
|
while process.poll() is None:
|
71
76
|
readylist, _, _ = select.select([process.stdout, process.stderr], [], [], 1)
|
72
|
-
|
73
|
-
|
77
|
+
for stream in (process.stdout, process.stderr):
|
78
|
+
buf = stream_buffer[stream]
|
79
|
+
if stream in readylist:
|
80
|
+
buf.append(stream.read(4096))
|
81
|
+
output, _, remaining = "".join(buf).rpartition("\n")
|
74
82
|
if output:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
if error_output:
|
79
|
-
print(error_output, end="", file=sys.stderr)
|
83
|
+
log_func[stream](output)
|
84
|
+
buf.clear()
|
85
|
+
buf.append(remaining)
|
80
86
|
except Exception as e:
|
81
87
|
print(f"Error reading process output: {str(e)}")
|
82
88
|
|
83
89
|
|
84
|
-
def _start_plot_process(gui_id, gui_class, config) -> None:
|
90
|
+
def _start_plot_process(gui_id, gui_class, config, logger=None) -> None:
|
85
91
|
"""
|
86
92
|
Start the plot in a new process.
|
93
|
+
|
94
|
+
Logger must be a logger object with "debug" and "error" functions,
|
95
|
+
or it can be left to "None" as default. None means output from the
|
96
|
+
process will not be captured.
|
87
97
|
"""
|
88
98
|
# pylint: disable=subprocess-run-check
|
89
|
-
command = [
|
90
|
-
|
91
|
-
"--
|
92
|
-
|
93
|
-
"--config",
|
94
|
-
config,
|
95
|
-
"--gui_class",
|
96
|
-
gui_class.__name__,
|
97
|
-
]
|
99
|
+
command = ["bec-gui-server", "--id", gui_id, "--gui_class", gui_class.__name__]
|
100
|
+
if config:
|
101
|
+
command.extend(["--config", config])
|
102
|
+
|
98
103
|
env_dict = os.environ.copy()
|
99
104
|
env_dict["PYTHONUNBUFFERED"] = "1"
|
105
|
+
if logger is None:
|
106
|
+
stdout_redirect = subprocess.DEVNULL
|
107
|
+
stderr_redirect = subprocess.DEVNULL
|
108
|
+
else:
|
109
|
+
stdout_redirect = subprocess.PIPE
|
110
|
+
stderr_redirect = subprocess.PIPE
|
111
|
+
|
100
112
|
process = subprocess.Popen(
|
101
|
-
command,
|
113
|
+
command,
|
114
|
+
text=True,
|
115
|
+
start_new_session=True,
|
116
|
+
stdout=stdout_redirect,
|
117
|
+
stderr=stderr_redirect,
|
118
|
+
env=env_dict,
|
102
119
|
)
|
103
|
-
|
104
|
-
|
120
|
+
if logger is None:
|
121
|
+
process_output_processing_thread = None
|
122
|
+
else:
|
123
|
+
process_output_processing_thread = threading.Thread(
|
124
|
+
target=_get_output, args=(process, logger)
|
125
|
+
)
|
126
|
+
process_output_processing_thread.start()
|
105
127
|
return process, process_output_processing_thread
|
106
128
|
|
107
129
|
|
@@ -113,7 +135,6 @@ class BECGuiClientMixin:
|
|
113
135
|
self.auto_updates = self._get_update_script()
|
114
136
|
self._target_endpoint = MessageEndpoints.scan_status()
|
115
137
|
self._selected_device = None
|
116
|
-
self.stderr_output = []
|
117
138
|
|
118
139
|
def _get_update_script(self) -> AutoUpdates | None:
|
119
140
|
eps = imd.entry_points(group="bec.widgets.auto_updates")
|
@@ -165,7 +186,7 @@ class BECGuiClientMixin:
|
|
165
186
|
if self._process is None or self._process.poll() is not None:
|
166
187
|
self._start_update_script()
|
167
188
|
self._process, self._process_output_processing_thread = _start_plot_process(
|
168
|
-
self._gui_id, self.__class__, self._client._service_config.
|
189
|
+
self._gui_id, self.__class__, self._client._service_config.config_path
|
169
190
|
)
|
170
191
|
while not self.gui_is_alive():
|
171
192
|
print("Waiting for GUI to start...")
|
@@ -185,19 +206,10 @@ class BECGuiClientMixin:
|
|
185
206
|
self._client.shutdown()
|
186
207
|
if self._process:
|
187
208
|
self._process.terminate()
|
188
|
-
self._process_output_processing_thread
|
209
|
+
if self._process_output_processing_thread:
|
210
|
+
self._process_output_processing_thread.join()
|
189
211
|
self._process = None
|
190
212
|
|
191
|
-
def print_log(self) -> None:
|
192
|
-
"""
|
193
|
-
Print the log of the plot process.
|
194
|
-
"""
|
195
|
-
if self._process is None:
|
196
|
-
return
|
197
|
-
print("".join(self.stderr_output))
|
198
|
-
# Flush list
|
199
|
-
self.stderr_output.clear()
|
200
|
-
|
201
213
|
|
202
214
|
class RPCResponseTimeoutError(Exception):
|
203
215
|
"""Exception raised when an RPC response is not received within the expected time."""
|
bec_widgets/cli/server.py
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
import inspect
|
2
|
+
import signal
|
3
|
+
import sys
|
4
|
+
from contextlib import redirect_stderr, redirect_stdout
|
2
5
|
from typing import Union
|
3
6
|
|
4
7
|
from bec_lib.endpoints import MessageEndpoints
|
8
|
+
from bec_lib.logger import bec_logger
|
9
|
+
from bec_lib.service_config import ServiceConfig
|
5
10
|
from bec_lib.utils.import_utils import lazy_import
|
6
11
|
from qtpy.QtCore import QTimer
|
7
12
|
|
8
13
|
from bec_widgets.cli.rpc_register import RPCRegister
|
9
14
|
from bec_widgets.utils import BECDispatcher
|
10
15
|
from bec_widgets.utils.bec_connector import BECConnector
|
16
|
+
from bec_widgets.utils.bec_dispatcher import QtRedisConnector
|
11
17
|
from bec_widgets.widgets.dock.dock_area import BECDockArea
|
12
18
|
from bec_widgets.widgets.figure import BECFigure
|
13
19
|
|
14
20
|
messages = lazy_import("bec_lib.messages")
|
21
|
+
logger = bec_logger.logger
|
15
22
|
|
16
23
|
|
17
24
|
class BECWidgetsCLIServer:
|
@@ -114,6 +121,23 @@ class BECWidgetsCLIServer:
|
|
114
121
|
self.client.shutdown()
|
115
122
|
|
116
123
|
|
124
|
+
class SimpleFileLikeFromLogOutputFunc:
|
125
|
+
def __init__(self, log_func):
|
126
|
+
self._log_func = log_func
|
127
|
+
|
128
|
+
def write(self, buffer):
|
129
|
+
for line in buffer.rstrip().splitlines():
|
130
|
+
line = line.rstrip()
|
131
|
+
if line:
|
132
|
+
self._log_func(line)
|
133
|
+
|
134
|
+
def flush(self):
|
135
|
+
return
|
136
|
+
|
137
|
+
def close(self):
|
138
|
+
return
|
139
|
+
|
140
|
+
|
117
141
|
def main():
|
118
142
|
import argparse
|
119
143
|
import os
|
@@ -125,16 +149,6 @@ def main():
|
|
125
149
|
|
126
150
|
import bec_widgets
|
127
151
|
|
128
|
-
app = QApplication(sys.argv)
|
129
|
-
app.setApplicationName("BEC Figure")
|
130
|
-
module_path = os.path.dirname(bec_widgets.__file__)
|
131
|
-
icon = QIcon()
|
132
|
-
icon.addFile(os.path.join(module_path, "assets", "bec_widgets_icon.png"), size=QSize(48, 48))
|
133
|
-
app.setWindowIcon(icon)
|
134
|
-
|
135
|
-
win = QMainWindow()
|
136
|
-
win.setWindowTitle("BEC Widgets")
|
137
|
-
|
138
152
|
parser = argparse.ArgumentParser(description="BEC Widgets CLI Server")
|
139
153
|
parser.add_argument("--id", type=str, help="The id of the server")
|
140
154
|
parser.add_argument(
|
@@ -142,7 +156,7 @@ def main():
|
|
142
156
|
type=str,
|
143
157
|
help="Name of the gui class to be rendered. Possible values: \n- BECFigure\n- BECDockArea",
|
144
158
|
)
|
145
|
-
parser.add_argument("--config", type=str, help="Config
|
159
|
+
parser.add_argument("--config", type=str, help="Config file")
|
146
160
|
|
147
161
|
args = parser.parse_args()
|
148
162
|
|
@@ -157,15 +171,44 @@ def main():
|
|
157
171
|
)
|
158
172
|
gui_class = BECFigure
|
159
173
|
|
160
|
-
|
174
|
+
with redirect_stdout(SimpleFileLikeFromLogOutputFunc(logger.debug)):
|
175
|
+
with redirect_stderr(SimpleFileLikeFromLogOutputFunc(logger.error)):
|
176
|
+
app = QApplication(sys.argv)
|
177
|
+
app.setApplicationName("BEC Figure")
|
178
|
+
module_path = os.path.dirname(bec_widgets.__file__)
|
179
|
+
icon = QIcon()
|
180
|
+
icon.addFile(
|
181
|
+
os.path.join(module_path, "assets", "bec_widgets_icon.png"), size=QSize(48, 48)
|
182
|
+
)
|
183
|
+
app.setWindowIcon(icon)
|
184
|
+
|
185
|
+
win = QMainWindow()
|
186
|
+
win.setWindowTitle("BEC Widgets")
|
187
|
+
|
188
|
+
service_config = ServiceConfig(args.config)
|
189
|
+
bec_logger.configure(
|
190
|
+
service_config.redis,
|
191
|
+
QtRedisConnector,
|
192
|
+
service_name="BECWidgetsCLIServer",
|
193
|
+
service_config=service_config.service_config,
|
194
|
+
)
|
195
|
+
server = BECWidgetsCLIServer(gui_id=args.id, config=service_config, gui_class=gui_class)
|
196
|
+
|
197
|
+
gui = server.gui
|
198
|
+
win.setCentralWidget(gui)
|
199
|
+
win.resize(800, 600)
|
200
|
+
win.show()
|
201
|
+
|
202
|
+
app.aboutToQuit.connect(server.shutdown)
|
203
|
+
|
204
|
+
def sigint_handler(*args):
|
205
|
+
# display message, for people to let it terminate gracefully
|
206
|
+
print("Caught SIGINT, exiting")
|
207
|
+
app.quit()
|
161
208
|
|
162
|
-
|
163
|
-
win.setCentralWidget(gui)
|
164
|
-
win.resize(800, 600)
|
165
|
-
win.show()
|
209
|
+
signal.signal(signal.SIGINT, sigint_handler)
|
166
210
|
|
167
|
-
|
168
|
-
sys.exit(app.exec())
|
211
|
+
sys.exit(app.exec())
|
169
212
|
|
170
213
|
|
171
214
|
if __name__ == "__main__": # pragma: no cover
|
@@ -66,6 +66,11 @@ class QtRedisConnector(RedisConnector):
|
|
66
66
|
cb(msg.content, msg.metadata)
|
67
67
|
|
68
68
|
|
69
|
+
class BECClientWithoutLoggerInit(BECClient):
|
70
|
+
def _initialize_logger(self):
|
71
|
+
return
|
72
|
+
|
73
|
+
|
69
74
|
class BECDispatcher:
|
70
75
|
"""Utility class to keep track of slots connected to a particular redis connector"""
|
71
76
|
|
@@ -79,7 +84,7 @@ class BECDispatcher:
|
|
79
84
|
cls._initialized = False
|
80
85
|
return cls._instance
|
81
86
|
|
82
|
-
def __init__(self, client=None, config: str = None):
|
87
|
+
def __init__(self, client=None, config: str | ServiceConfig = None):
|
83
88
|
if self._initialized:
|
84
89
|
return
|
85
90
|
|
@@ -91,13 +96,16 @@ class BECDispatcher:
|
|
91
96
|
|
92
97
|
if self.client is None:
|
93
98
|
if config is not None:
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
99
|
+
if not isinstance(config, ServiceConfig):
|
100
|
+
# config is supposed to be a path
|
101
|
+
config = ServiceConfig(config)
|
102
|
+
self.client = BECClientWithoutLoggerInit(
|
103
|
+
config=config, connector_cls=QtRedisConnector
|
98
104
|
) # , forced=True)
|
99
105
|
else:
|
100
|
-
self.client =
|
106
|
+
self.client = BECClientWithoutLoggerInit(
|
107
|
+
connector_cls=QtRedisConnector
|
108
|
+
) # , forced=True)
|
101
109
|
else:
|
102
110
|
if self.client.started:
|
103
111
|
# have to reinitialize client to use proper connector
|
File without changes
|