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 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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.61.0
3
+ Version: 0.63.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
@@ -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())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.61.0
3
+ Version: 0.63.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=3PU2LONUl10zIOD4UCPQgA6vVBtniabww1MQkTMce7I,7995
3
3
  .pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=M5IR-g_0B-sq_qGAYP4A8BReh6U9HcGKxeAmMGGjPHs,6792
5
+ CHANGELOG.md,sha256=SSIvLIsLoMqELDdBJGpxD-i6mL6yHf9zOfv5Sslx0ZA,6807
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=nwiL8DuDWzYjWMcR_JGIZL2uTa8UFyC-NfJHBKxSpEI,1302
7
+ PKG-INFO,sha256=7zmXAhyzvbGnDsRQ9BIOv4jDaDOHgaiY6X2dXspqEM4,1302
8
8
  README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
9
- pyproject.toml,sha256=itvsOSpNTbXMXrClzMA00l9i7ATGsAqrSifK5IB2u5I,2115
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=6mzmRe_pjuz-3CoBJZkxaa05VzAmPLi_cDJ3uljmw8Y,54363
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=VRLujiICU_Gq0mO1Hr15YwjlxU7OcAzqeoM8QHqSubM,1032
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=Og0NuUsTs8HdwKtpHnycGmH8wCqOeYgj2ozlYRJ-Drk,249
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=EfrElcZVh9jHt_0kIXdDtc7z3ErYGqwmVMxC_AHSGU0,370
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.61.0.dist-info/METADATA,sha256=nwiL8DuDWzYjWMcR_JGIZL2uTa8UFyC-NfJHBKxSpEI,1302
167
- bec_widgets-0.61.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
168
- bec_widgets-0.61.0.dist-info/entry_points.txt,sha256=80s2YKCNziN2ROUYbpDRyEmiejMf_dshmiYCdN7qNsU,70
169
- bec_widgets-0.61.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
170
- bec_widgets-0.61.0.dist-info/RECORD,,
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,,
@@ -1,8 +1,118 @@
1
1
  (user.customisation)=
2
2
  # Customisation
3
3
 
4
- BEC Widgets are designed to be used with QtDesigner to quicly design GUI.
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
+
@@ -12,6 +12,7 @@ bec_figure/
12
12
  spiral_progress_bar/
13
13
  website/
14
14
  buttons/
15
+ text_box/
15
16
  ```
16
17
 
17
18
 
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.61.0"
7
+ version = "0.63.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -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
+ )