bec-widgets 0.61.0__py3-none-any.whl → 0.63.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 +36 -30
- PKG-INFO +1 -1
- bec_widgets/cli/client.py +43 -0
- bec_widgets/cli/rpc_wigdet_handler.py +2 -0
- bec_widgets/widgets/text_box/__init__.py +0 -0
- bec_widgets/widgets/text_box/text_box.py +127 -0
- {bec_widgets-0.61.0.dist-info → bec_widgets-0.63.0.dist-info}/METADATA +1 -1
- {bec_widgets-0.61.0.dist-info → bec_widgets-0.63.0.dist-info}/RECORD +16 -12
- docs/user/customisation.md +111 -1
- docs/user/widgets/text_box.md +33 -0
- docs/user/widgets/widgets.md +1 -0
- pyproject.toml +1 -1
- tests/unit_tests/test_text_box_widget.py +55 -0
- {bec_widgets-0.61.0.dist-info → bec_widgets-0.63.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.61.0.dist-info → bec_widgets-0.63.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.61.0.dist-info → bec_widgets-0.63.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -2,6 +2,42 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
+
## v0.63.0 (2024-06-13)
|
6
|
+
|
7
|
+
### Documentation
|
8
|
+
|
9
|
+
* docs: add documentation ([`bc709c4`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bc709c4184c985d4e721f9ea7d1b3dad5e9153a7))
|
10
|
+
|
11
|
+
### Feature
|
12
|
+
|
13
|
+
* feat: add textbox widget ([`d9d4e3c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d9d4e3c9bf73ab2a5629c2867b50fc91e69489ec))
|
14
|
+
|
15
|
+
### Refactor
|
16
|
+
|
17
|
+
* refactor: add pydantic config, add change_theme ([`6b8432f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6b8432f5b20a71175a3537b5f6832b76e3b67d73))
|
18
|
+
|
19
|
+
### Test
|
20
|
+
|
21
|
+
* test: add test for text box ([`b49462a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b49462abeb186e56bac79d2ef0b0add1ef28a1a5))
|
22
|
+
|
23
|
+
### Unknown
|
24
|
+
|
25
|
+
* Revert "feat: implement non-polling, interruptible waiting of gui instruction response with timeout"
|
26
|
+
|
27
|
+
This reverts commit abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3 ([`fe04dd8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fe04dd80e59a0e74f7fdea603e0642707ecc7c2a))
|
28
|
+
|
29
|
+
|
30
|
+
## v0.62.0 (2024-06-12)
|
31
|
+
|
32
|
+
### Feature
|
33
|
+
|
34
|
+
* feat: implement non-polling, interruptible waiting of gui instruction response with timeout ([`abc6caa`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/abc6caa2d0b6141dfbe1f3d025f78ae14deddcb3))
|
35
|
+
|
36
|
+
### Unknown
|
37
|
+
|
38
|
+
* doc: add documentation about creating custom GUI applications embedding BEC Widgets ([`17a0068`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/17a00687579f5efab1990cd83862ec0e78198633))
|
39
|
+
|
40
|
+
|
5
41
|
## v0.61.0 (2024-06-12)
|
6
42
|
|
7
43
|
### Feature
|
@@ -131,33 +167,3 @@
|
|
131
167
|
|
132
168
|
|
133
169
|
## v0.57.5 (2024-06-06)
|
134
|
-
|
135
|
-
### Documentation
|
136
|
-
|
137
|
-
* docs(figure): docs adjusted to be compatible with new signature ([`c037b87`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c037b87675af91b26e8c7c60e76622d4ed4cf5d5))
|
138
|
-
|
139
|
-
### Fix
|
140
|
-
|
141
|
-
* fix(waveform): added .plot method with the same signature as BECFigure.plot ([`8479caf`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8479caf53a7325788ca264e5bd9aee01f1d4c5a0))
|
142
|
-
|
143
|
-
* fix(plot_base): .plot removed from plot_base.py, because there is no use case for it ([`82e2c89`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/82e2c898d2e26f786b2d481f85c647472675e75b))
|
144
|
-
|
145
|
-
### Refactor
|
146
|
-
|
147
|
-
* refactor(figure): logic for .add_image and .image consolidated; logic for .add_plot and .plot consolidated ([`52bc322`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/52bc322b2b8d3ef92ff3480e61bddaf32464f976))
|
148
|
-
|
149
|
-
|
150
|
-
## v0.57.4 (2024-06-06)
|
151
|
-
|
152
|
-
### Fix
|
153
|
-
|
154
|
-
* fix(docks): set_title do update dock internal _name now ([`15cbc21`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/15cbc21e5bb3cf85f5822d44a2b3665b5aa2f346))
|
155
|
-
|
156
|
-
* fix(docks): docks widget_list adn dockarea panels return values fixed ([`ffae5ee`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ffae5ee54e6b43da660131092452adff195ba4fb))
|
157
|
-
|
158
|
-
|
159
|
-
## v0.57.3 (2024-06-06)
|
160
|
-
|
161
|
-
### Documentation
|
162
|
-
|
163
|
-
* docs(bar): docs updated ([`4be0d14`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4be0d14b7445c2322c2aef86257db168a841265c))
|
PKG-INFO
CHANGED
bec_widgets/cli/client.py
CHANGED
@@ -17,6 +17,7 @@ class Widgets(str, enum.Enum):
|
|
17
17
|
BECDockArea = "BECDockArea"
|
18
18
|
BECFigure = "BECFigure"
|
19
19
|
SpiralProgressBar = "SpiralProgressBar"
|
20
|
+
TextBox = "TextBox"
|
20
21
|
WebsiteWidget = "WebsiteWidget"
|
21
22
|
|
22
23
|
|
@@ -1897,6 +1898,48 @@ class SpiralProgressBar(RPCBase):
|
|
1897
1898
|
"""
|
1898
1899
|
|
1899
1900
|
|
1901
|
+
class StopButton(RPCBase):
|
1902
|
+
@property
|
1903
|
+
@rpc_call
|
1904
|
+
def config_dict(self) -> "dict":
|
1905
|
+
"""
|
1906
|
+
Get the configuration of the widget.
|
1907
|
+
|
1908
|
+
Returns:
|
1909
|
+
dict: The configuration of the widget.
|
1910
|
+
"""
|
1911
|
+
|
1912
|
+
@rpc_call
|
1913
|
+
def get_all_rpc(self) -> "dict":
|
1914
|
+
"""
|
1915
|
+
Get all registered RPC objects.
|
1916
|
+
"""
|
1917
|
+
|
1918
|
+
|
1919
|
+
class TextBox(RPCBase):
|
1920
|
+
@rpc_call
|
1921
|
+
def set_color(self, background_color: str, font_color: str) -> None:
|
1922
|
+
"""
|
1923
|
+
Set the background color of the Widget.
|
1924
|
+
|
1925
|
+
Args:
|
1926
|
+
background_color (str): The color to set the background in HEX.
|
1927
|
+
font_color (str): The color to set the font in HEX.
|
1928
|
+
"""
|
1929
|
+
|
1930
|
+
@rpc_call
|
1931
|
+
def set_text(self, text: str) -> None:
|
1932
|
+
"""
|
1933
|
+
Set the text of the Widget
|
1934
|
+
"""
|
1935
|
+
|
1936
|
+
@rpc_call
|
1937
|
+
def set_font_size(self, size: int) -> None:
|
1938
|
+
"""
|
1939
|
+
Set the font size of the text in the Widget.
|
1940
|
+
"""
|
1941
|
+
|
1942
|
+
|
1900
1943
|
class WebsiteWidget(RPCBase):
|
1901
1944
|
@rpc_call
|
1902
1945
|
def set_url(self, url: str) -> None:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from bec_widgets.utils import BECConnector
|
2
2
|
from bec_widgets.widgets.figure import BECFigure
|
3
3
|
from bec_widgets.widgets.spiral_progress_bar.spiral_progress_bar import SpiralProgressBar
|
4
|
+
from bec_widgets.widgets.text_box.text_box import TextBox
|
4
5
|
from bec_widgets.widgets.website.website import WebsiteWidget
|
5
6
|
|
6
7
|
|
@@ -11,6 +12,7 @@ class RPCWidgetHandler:
|
|
11
12
|
"BECFigure": BECFigure,
|
12
13
|
"SpiralProgressBar": SpiralProgressBar,
|
13
14
|
"Website": WebsiteWidget,
|
15
|
+
"TextBox": TextBox,
|
14
16
|
}
|
15
17
|
|
16
18
|
@staticmethod
|
File without changes
|
@@ -0,0 +1,127 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
from pydantic import Field, field_validator
|
4
|
+
from qtpy.QtWidgets import QTextEdit
|
5
|
+
|
6
|
+
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
|
7
|
+
from bec_widgets.utils.colors import Colors
|
8
|
+
|
9
|
+
|
10
|
+
class TextBoxConfig(ConnectionConfig):
|
11
|
+
|
12
|
+
theme: str = Field("dark", description="The theme of the figure widget.")
|
13
|
+
font_color: str = Field("#FFF", description="The font color of the text")
|
14
|
+
background_color: str = Field("#000", description="The background color of the widget.")
|
15
|
+
font_size: int = Field(16, description="The font size of the text in the widget.")
|
16
|
+
text: str = Field("", description="The text to display in the widget.")
|
17
|
+
|
18
|
+
@classmethod
|
19
|
+
@field_validator("theme")
|
20
|
+
def validate_theme(cls, v):
|
21
|
+
"""Validate the theme of the figure widget."""
|
22
|
+
if v not in ["dark", "light"]:
|
23
|
+
raise ValueError("Theme must be either 'dark' or 'light'")
|
24
|
+
return v
|
25
|
+
|
26
|
+
_validate_font_color = field_validator("font_color")(Colors.validate_color)
|
27
|
+
_validate_background_color = field_validator("background_color")(Colors.validate_color)
|
28
|
+
|
29
|
+
|
30
|
+
class TextBox(BECConnector, QTextEdit):
|
31
|
+
|
32
|
+
USER_ACCESS = ["set_color", "set_text", "set_font_size"]
|
33
|
+
|
34
|
+
def __init__(self, text: str = "", parent=None, client=None, config=None, gui_id=None):
|
35
|
+
if config is None:
|
36
|
+
config = TextBoxConfig(widget_class=self.__class__.__name__)
|
37
|
+
else:
|
38
|
+
if isinstance(config, dict):
|
39
|
+
config = TextBoxConfig(**config)
|
40
|
+
self.config = config
|
41
|
+
super().__init__(client=client, config=config, gui_id=gui_id)
|
42
|
+
QTextEdit.__init__(self, parent=parent)
|
43
|
+
|
44
|
+
self.config = config
|
45
|
+
self.setReadOnly(True)
|
46
|
+
self.setGeometry(self.rect())
|
47
|
+
self.set_color(self.config.background_color, self.config.font_color)
|
48
|
+
if not text:
|
49
|
+
text = "<h1>Welcome to the BEC Widget TextBox</h1><p>A widget that allows user to display text in plain and HTML format.</p><p>This is an example of displaying HTML text.</p>"
|
50
|
+
self.set_text(text)
|
51
|
+
|
52
|
+
def change_theme(self) -> None:
|
53
|
+
"""
|
54
|
+
Change the theme of the figure widget.
|
55
|
+
"""
|
56
|
+
if self.config.theme == "dark":
|
57
|
+
theme = "light"
|
58
|
+
font_color = "#000"
|
59
|
+
background_color = "#FFF"
|
60
|
+
else:
|
61
|
+
theme = "dark"
|
62
|
+
font_color = "#FFF"
|
63
|
+
background_color = "#000"
|
64
|
+
self.config.theme = theme
|
65
|
+
self.set_color(background_color, font_color)
|
66
|
+
|
67
|
+
def set_color(self, background_color: str, font_color: str) -> None:
|
68
|
+
"""Set the background color of the widget.
|
69
|
+
|
70
|
+
Args:
|
71
|
+
background_color (str): The color to set the background in HEX.
|
72
|
+
font_color (str): The color to set the font in HEX.
|
73
|
+
|
74
|
+
"""
|
75
|
+
self.config.background_color = background_color
|
76
|
+
self.config.font_color = font_color
|
77
|
+
self._update_stylesheet()
|
78
|
+
|
79
|
+
def set_font_size(self, size: int) -> None:
|
80
|
+
"""Set the font size of the text in the widget.
|
81
|
+
|
82
|
+
Args:
|
83
|
+
size (int): The font size to set.
|
84
|
+
"""
|
85
|
+
self.config.font_size = size
|
86
|
+
self._update_stylesheet()
|
87
|
+
|
88
|
+
def _update_stylesheet(self):
|
89
|
+
"""Update the stylesheet of the widget."""
|
90
|
+
self.setStyleSheet(
|
91
|
+
f"background-color: {self.config.background_color}; color: {self.config.font_color}; font-size: {self.config.font_size}px"
|
92
|
+
)
|
93
|
+
|
94
|
+
def set_text(self, text: str) -> None:
|
95
|
+
"""Set the text of the widget.
|
96
|
+
|
97
|
+
Args:
|
98
|
+
text (str): The text to set.
|
99
|
+
"""
|
100
|
+
if self.is_html(text):
|
101
|
+
self.setHtml(text)
|
102
|
+
else:
|
103
|
+
self.setPlainText(text)
|
104
|
+
self.config.text = text
|
105
|
+
|
106
|
+
def is_html(self, text: str) -> bool:
|
107
|
+
"""Check if the text contains HTML tags.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
text (str): The text to check.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
bool: True if the text contains HTML tags, False otherwise.
|
114
|
+
"""
|
115
|
+
return bool(re.search(r"<[a-zA-Z/][^>]*>", text))
|
116
|
+
|
117
|
+
|
118
|
+
if __name__ == "__main__":
|
119
|
+
import sys
|
120
|
+
|
121
|
+
from qtpy.QtWidgets import QApplication
|
122
|
+
|
123
|
+
app = QApplication(sys.argv)
|
124
|
+
|
125
|
+
widget = TextBox()
|
126
|
+
widget.show()
|
127
|
+
sys.exit(app.exec())
|
@@ -2,11 +2,11 @@
|
|
2
2
|
.gitlab-ci.yml,sha256=3PU2LONUl10zIOD4UCPQgA6vVBtniabww1MQkTMce7I,7995
|
3
3
|
.pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
|
4
4
|
.readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
|
5
|
-
CHANGELOG.md,sha256=
|
5
|
+
CHANGELOG.md,sha256=SSIvLIsLoMqELDdBJGpxD-i6mL6yHf9zOfv5Sslx0ZA,6807
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=7zmXAhyzvbGnDsRQ9BIOv4jDaDOHgaiY6X2dXspqEM4,1302
|
8
8
|
README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=sZcekDO1IZEFkY_FiioZBTW4i6p__x-iQpMLbVq_rqk,2115
|
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
|
@@ -17,11 +17,11 @@ bec_widgets/assets/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3i
|
|
17
17
|
bec_widgets/assets/terminal_icon.png,sha256=bJl7Tft4Fi2uxvuXI8o14uMHnI9eAWKSU2uftXCH9ws,3889
|
18
18
|
bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
|
19
19
|
bec_widgets/cli/auto_updates.py,sha256=DyBV3HnjMSH-cvVkYNcDiYKVf0Xut4Qy2qGQqkW47Bw,4833
|
20
|
-
bec_widgets/cli/client.py,sha256=
|
20
|
+
bec_widgets/cli/client.py,sha256=PkKPeR4KJjJP-DOPTq3yYJIuWlwXLHjTyZunCYSsU1I,55332
|
21
21
|
bec_widgets/cli/client_utils.py,sha256=7u8P9EYgLPJuAcHxnFiZi-gCZohO3vAn0W7dqsSrs4M,10660
|
22
22
|
bec_widgets/cli/generate_cli.py,sha256=DIaGz7nhwef3ebIaP4LtiUC3q7MoM1swJ_e0SgAO2jo,6901
|
23
23
|
bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
|
24
|
-
bec_widgets/cli/rpc_wigdet_handler.py,sha256=
|
24
|
+
bec_widgets/cli/rpc_wigdet_handler.py,sha256=1oE2TSbwQdfLEaZiscyDX2eExHsenp2BF5Lwy8PE6LA,1118
|
25
25
|
bec_widgets/cli/server.py,sha256=rsj31Vsx6ayThNe4PQelQFahGjYXFZjfrNyB2fnm6Ro,5737
|
26
26
|
bec_widgets/examples/__init__.py,sha256=WWQ0cu7m8sA4Ehy-DWdTIqSISjaHsbxhsNmNrMnhDZU,202
|
27
27
|
bec_widgets/examples/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -87,6 +87,8 @@ bec_widgets/widgets/scan_control/scan_control.py,sha256=B5n2U2iVtTCY3Tx93JyBqzGC
|
|
87
87
|
bec_widgets/widgets/spiral_progress_bar/__init__.py,sha256=4efbtcqCToMIw5bkQrTzy2TzuBCXvlhuUPh1bYC_Yzg,51
|
88
88
|
bec_widgets/widgets/spiral_progress_bar/ring.py,sha256=7i5oKpW8eUQGvLyKce2-2rlaGDVLec__DoWp6hfJlRw,10524
|
89
89
|
bec_widgets/widgets/spiral_progress_bar/spiral_progress_bar.py,sha256=cMi4g7zNTLrkkzZ9ChiIBTaqigDCYwzrgA2iRmq9dUI,24050
|
90
|
+
bec_widgets/widgets/text_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
91
|
+
bec_widgets/widgets/text_box/text_box.py,sha256=kykQ_Zcxh8IGcPEP5-oGGQwoZEpY9vhxRIM8TY8kTYg,4240
|
90
92
|
bec_widgets/widgets/toolbar/__init__.py,sha256=d-TP4_cr_VbpwreMM4ePnfZ5YXsEPQ45ibEf75nuGoE,36
|
91
93
|
bec_widgets/widgets/toolbar/toolbar.py,sha256=e0zCD_0q7K4NVhrzD8001Qvfxt-VhqHTgofchS9NgCM,5125
|
92
94
|
bec_widgets/widgets/website/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -109,7 +111,7 @@ docs/assets/index_user_guide.svg,sha256=sRjKwOHVJStBYIQUFVcnfmbeXd2qAp0HYjleSp66
|
|
109
111
|
docs/assets/rocket_launch_48dp.svg,sha256=pdrPrBcKWUa5OlgWKM0B6TA6qAW7E57d7C7YW2r1OT8,1070
|
110
112
|
docs/developer/developer.md,sha256=7Z6sfkk_7BgwZ2vaX4z5_cJrs0miyeAYSGpqMbyBmOI,415
|
111
113
|
docs/introduction/introduction.md,sha256=wp7jmhkUtJnSnEnmIAZGUcau_3-5e5-FohvZb63khw4,1432
|
112
|
-
docs/user/customisation.md,sha256=
|
114
|
+
docs/user/customisation.md,sha256=MXqbljqokDXF3VhCeia1PITZe1mx1J3FfLTJ66TlaUA,3172
|
113
115
|
docs/user/user.md,sha256=uCTcjclIi6rdjYRQebko6bWFEVsjyfshsVU3BDYrC-Y,1403
|
114
116
|
docs/user/api_reference/api_reference.md,sha256=q2Imc48Rq6GcAP0R4bS3KuW5ptZZdsV4wxGJb3JJQHg,174
|
115
117
|
docs/user/applications/applications.md,sha256=yOECfaYRUEDIxF-O0duOwSJlG4f93RylrpMjbw1-8Dg,100
|
@@ -127,9 +129,10 @@ docs/user/widgets/motor.gif,sha256=FtaWdRHx4UZaGJPpq8LNhMMgX4PFcAB6IZ93JCMEh_w,2
|
|
127
129
|
docs/user/widgets/progress_bar.gif,sha256=5jh0Zw2BBGPuNxszV1DBLJCb4_6glIRX-U2ABjnsK2k,5263592
|
128
130
|
docs/user/widgets/scatter_2D.gif,sha256=yHpsuAUseMafJjI_J5BcOhmE3nu9VFn_Xm9XHzJaH5I,13188862
|
129
131
|
docs/user/widgets/spiral_progress_bar.md,sha256=QTgUDIl6XPuK_HwSfB6sNijZ4bss26biDg6B_mJ8Pxk,2208
|
132
|
+
docs/user/widgets/text_box.md,sha256=i40AxKJP0PxrYW0x0up1VIovPFvemsaZoosGjOn4iZE,931
|
130
133
|
docs/user/widgets/w1D.gif,sha256=tuHbleJpl6bJFNNC2OdndF5LF7IyfvlkFCMGZajrQPs,622773
|
131
134
|
docs/user/widgets/website.md,sha256=wfudAupdtHX-Sfritg0xMWXZLLczJ4XwMLNWvu6ww-w,705
|
132
|
-
docs/user/widgets/widgets.md,sha256=
|
135
|
+
docs/user/widgets/widgets.md,sha256=NzRfrgd4LWmZHa2Cs_1G59LeY5uAlFdy5aP00AtGAjk,380
|
133
136
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
134
137
|
tests/end-2-end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
135
138
|
tests/end-2-end/conftest.py,sha256=taLqiYVzOhJjMre5ypgQjB7wzSXP4soKANW3XfAjems,1773
|
@@ -154,6 +157,7 @@ tests/unit_tests/test_rpc_register.py,sha256=hECjZEimd440mwRrO0rg7L3PKN7__3DgjmE
|
|
154
157
|
tests/unit_tests/test_scan_control.py,sha256=7dtGpE0g4FqUhhQeCkyJl-9o7NH3DFZJgEaqDmBYbBc,7551
|
155
158
|
tests/unit_tests/test_spiral_progress_bar.py,sha256=yak3N9-TmEM3lQZPSROL4cAx9mior__se1XADlMScks,12418
|
156
159
|
tests/unit_tests/test_stop_button.py,sha256=hOoWO0emkvd5bR_EExxCnKsiZgXKqf_uIGTwzWLxhDw,704
|
160
|
+
tests/unit_tests/test_text_box_widget.py,sha256=cT0uEHt_6d-FwST0A_wE9sFW9E3F_nJbKhuBAeU4yHg,1862
|
157
161
|
tests/unit_tests/test_waveform1d.py,sha256=j9-CCE0BkFVI3Gnv8pjV1gc9HwA5PYG0_ox1oZ60F6w,15272
|
158
162
|
tests/unit_tests/test_website_widget.py,sha256=fBADIJJBAHU4Ro7u95kdemFVNv196UOcuO9oLHuHt8A,761
|
159
163
|
tests/unit_tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
|
@@ -163,8 +167,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
|
|
163
167
|
tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
|
164
168
|
tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
165
169
|
tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
|
166
|
-
bec_widgets-0.
|
167
|
-
bec_widgets-0.
|
168
|
-
bec_widgets-0.
|
169
|
-
bec_widgets-0.
|
170
|
-
bec_widgets-0.
|
170
|
+
bec_widgets-0.63.0.dist-info/METADATA,sha256=7zmXAhyzvbGnDsRQ9BIOv4jDaDOHgaiY6X2dXspqEM4,1302
|
171
|
+
bec_widgets-0.63.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
172
|
+
bec_widgets-0.63.0.dist-info/entry_points.txt,sha256=80s2YKCNziN2ROUYbpDRyEmiejMf_dshmiYCdN7qNsU,70
|
173
|
+
bec_widgets-0.63.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
174
|
+
bec_widgets-0.63.0.dist-info/RECORD,,
|
docs/user/customisation.md
CHANGED
@@ -1,8 +1,118 @@
|
|
1
1
|
(user.customisation)=
|
2
2
|
# Customisation
|
3
3
|
|
4
|
-
BEC Widgets
|
4
|
+
## Leveraging BEC Widgets in custom GUI applications
|
5
5
|
|
6
|
+
BEC Widgets can be used to compose a complete Qt graphical application, along with
|
7
|
+
other QWidgets. The only requirement is to connect to BEC servers in order to get
|
8
|
+
data, or to interact with BEC components. This role is devoted to the BECDispatcher,
|
9
|
+
a singleton object which has to be instantiated **after the QApplication is created**.
|
10
|
+
|
11
|
+
A typical BEC Widgets custom application "main" entry point should follow the template
|
12
|
+
below:
|
13
|
+
|
14
|
+
```
|
15
|
+
import argparse
|
16
|
+
import sys
|
17
|
+
|
18
|
+
from bec_widgets.utils.bec_dispatcher import BECDispatcher
|
19
|
+
from qtpy.QtWidgets import QApplication
|
20
|
+
|
21
|
+
# optional command line arguments processing
|
22
|
+
parser = argparse.ArgumentParser(description="...")
|
23
|
+
parser.add_argument( ...)
|
24
|
+
...
|
25
|
+
args = parser.parse_args()
|
26
|
+
|
27
|
+
# creation of the Qt application
|
28
|
+
app = QApplication([])
|
29
|
+
|
30
|
+
# creation of BEC Dispatcher
|
31
|
+
# /!\ important: after the QApplication has been instantiated
|
32
|
+
bec_dispatcher = BECDispatcher()
|
33
|
+
client = bec_dispatcher.client
|
34
|
+
client.start()
|
35
|
+
|
36
|
+
# (optional) processing of command line args,
|
37
|
+
# creation of a main window depending on the command line arguments (or not)
|
38
|
+
if args.xxx == "...":
|
39
|
+
window = ...
|
40
|
+
|
41
|
+
# display of the main window and start of Qt event loop
|
42
|
+
window.show()
|
43
|
+
sys.exit(app.exec())
|
44
|
+
```
|
45
|
+
|
46
|
+
The main "window" object presents the layout of widgets to the user and allows
|
47
|
+
users to interact. BEC Widgets must be placed in the window:
|
48
|
+
|
49
|
+
```
|
50
|
+
from qtpy.QWidgets import QMainWindow
|
51
|
+
from bec_widgets.widgets import BECFigure
|
52
|
+
|
53
|
+
window = QMainWindow()
|
54
|
+
bec_figure = BECFigure(gui_id="my_gui_app_id")
|
55
|
+
window.setCentralWidget(bec_figure)
|
56
|
+
|
57
|
+
# prepare to plot samx motor vs bpm4i value
|
58
|
+
bec_figure.plot(x_name="samx", y_name="bpm4i")
|
59
|
+
```
|
60
|
+
|
61
|
+
In the example just above, the resulting application will show a plot of samx
|
62
|
+
positions on the horizontal axis, and beam intensity on the vertical axis
|
63
|
+
(when the next scan will be started).
|
64
|
+
|
65
|
+
It is important to ensure proper cleanup of the resources is done when application
|
66
|
+
quits:
|
67
|
+
|
68
|
+
```
|
69
|
+
def final_cleanup():
|
70
|
+
bec_figure.clear_all()
|
71
|
+
bec_figure.client.shutdown()
|
72
|
+
|
73
|
+
window.aboutToQuit.connect(final_cleanup)
|
74
|
+
```
|
75
|
+
|
76
|
+
Final example:
|
77
|
+
|
78
|
+
```
|
79
|
+
import sys
|
80
|
+
from qtpy.QtWidgets import QMainWindow, QApplication
|
81
|
+
from bec_widgets.widgets import BECFigure
|
82
|
+
from bec_widgets.utils.bec_dispatcher import BECDispatcher
|
83
|
+
|
84
|
+
# creation of the Qt application
|
85
|
+
app = QApplication([])
|
86
|
+
|
87
|
+
# creation of BEC Dispatcher
|
88
|
+
bec_dispatcher = BECDispatcher()
|
89
|
+
client = bec_dispatcher.client
|
90
|
+
client.start()
|
91
|
+
|
92
|
+
# creation of main window
|
93
|
+
window = QMainWindow()
|
94
|
+
|
95
|
+
# inserting BEC Widgets
|
96
|
+
bec_figure = BECFigure(parent=window, gui_id="my_gui_app_id")
|
97
|
+
window.setCentralWidget(bec_figure)
|
98
|
+
|
99
|
+
bec_figure.plot(x_name="samx", y_name="bpm4i")
|
100
|
+
|
101
|
+
# ensuring proper cleanup
|
102
|
+
def final_cleanup():
|
103
|
+
bec_figure.clear_all()
|
104
|
+
bec_figure.client.shutdown()
|
105
|
+
|
106
|
+
app.aboutToQuit.connect(final_cleanup)
|
107
|
+
|
108
|
+
# execution
|
109
|
+
window.show()
|
110
|
+
sys.exit(app.exec())
|
111
|
+
```
|
112
|
+
|
113
|
+
## Writing applications using Qt Designer
|
114
|
+
|
115
|
+
BEC Widgets are designed to be used with QtDesigner to quickly design GUI.
|
6
116
|
|
7
117
|
## Example of promoting widgets in Qt Designer
|
8
118
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
(user.widgets.text_box)=
|
2
|
+
# [Text Box Widget](/api_reference/_autosummary/bec_widgets.cli.client.TextBoxWidget)
|
3
|
+
**Purpose:**
|
4
|
+
|
5
|
+
The Text Box Widget is a widget that allows you to display text within the BEC GUI. The widget can be used to display plain text or HTML text.
|
6
|
+
|
7
|
+
**Key Features:**
|
8
|
+
|
9
|
+
- set the text to display.
|
10
|
+
- automatically detects if the text is plain text or HTML text.
|
11
|
+
- set background color and font color.
|
12
|
+
|
13
|
+
**Code example:**
|
14
|
+
|
15
|
+
The following code snipped demonstrates how to create a `TextBox` widget using BEC Widgets within BEC.
|
16
|
+
```python
|
17
|
+
text_box = gui.add_dock().add_widget("TextBox")
|
18
|
+
# set the text to display
|
19
|
+
text_box.set_text("Hello, World!")
|
20
|
+
# set the background color and font color
|
21
|
+
text_box.set_color(backgroud_color="#FFF", font_color="#000")
|
22
|
+
# set the text to display as HTML
|
23
|
+
text_box.set_text("<h1>Welcome to BEC Widgets</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>")
|
24
|
+
```
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
|
docs/user/widgets/widgets.md
CHANGED
pyproject.toml
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
import re
|
2
|
+
from unittest import mock
|
3
|
+
|
4
|
+
import pytest
|
5
|
+
|
6
|
+
from bec_widgets.widgets.text_box.text_box import TextBox
|
7
|
+
|
8
|
+
from .client_mocks import mocked_client
|
9
|
+
|
10
|
+
|
11
|
+
@pytest.fixture
|
12
|
+
def text_box_widget(qtbot, mocked_client):
|
13
|
+
widget = TextBox(client=mocked_client)
|
14
|
+
qtbot.addWidget(widget)
|
15
|
+
qtbot.waitExposed(widget)
|
16
|
+
yield widget
|
17
|
+
widget.close()
|
18
|
+
|
19
|
+
|
20
|
+
def test_textbox_widget(text_box_widget):
|
21
|
+
"""Test the TextBox widget."""
|
22
|
+
text = "Hello World!"
|
23
|
+
text_box_widget.set_text(text)
|
24
|
+
assert text_box_widget.toPlainText() == text
|
25
|
+
|
26
|
+
text_box_widget.set_color("#FFDDC1", "#123456")
|
27
|
+
text_box_widget.set_font_size(20)
|
28
|
+
assert (
|
29
|
+
text_box_widget.styleSheet() == "background-color: #FFDDC1; color: #123456; font-size: 20px"
|
30
|
+
)
|
31
|
+
text_box_widget.set_color("white", "blue")
|
32
|
+
text_box_widget.set_font_size(14)
|
33
|
+
assert text_box_widget.styleSheet() == "background-color: white; color: blue; font-size: 14px"
|
34
|
+
text = "<h1>Welcome to PyQt6</h1><p>This is an example of displaying <strong>HTML</strong> text.</p>"
|
35
|
+
with mock.patch.object(text_box_widget, "setHtml") as mocked_set_html:
|
36
|
+
text_box_widget.set_text(text)
|
37
|
+
assert mocked_set_html.call_count == 1
|
38
|
+
assert mocked_set_html.call_args == mock.call(text)
|
39
|
+
|
40
|
+
|
41
|
+
def test_textbox_change_theme(text_box_widget):
|
42
|
+
"""Test change theme functionaility"""
|
43
|
+
# Default is dark theme
|
44
|
+
text_box_widget.change_theme()
|
45
|
+
assert text_box_widget.config.theme == "light"
|
46
|
+
assert (
|
47
|
+
text_box_widget.styleSheet()
|
48
|
+
== f"background-color: #FFF; color: #000; font-size: {text_box_widget.config.font_size}px"
|
49
|
+
)
|
50
|
+
text_box_widget.change_theme()
|
51
|
+
assert text_box_widget.config.theme == "dark"
|
52
|
+
assert (
|
53
|
+
text_box_widget.styleSheet()
|
54
|
+
== f"background-color: #000; color: #FFF; font-size: {text_box_widget.config.font_size}px"
|
55
|
+
)
|
File without changes
|
File without changes
|
File without changes
|