bec-widgets 0.87.1__py3-none-any.whl → 0.88.1__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 +72 -70
- PKG-INFO +1 -1
- bec_widgets/assets/designer_icons/BECWaveformWidget.png +0 -0
- bec_widgets/assets/designer_icons/colormap_selector.png +0 -0
- bec_widgets/assets/designer_icons/motor_map.png +0 -0
- bec_widgets/assets/toolbar_icons/add.svg +3 -0
- bec_widgets/assets/toolbar_icons/auto_range.svg +3 -0
- bec_widgets/assets/toolbar_icons/drag_pan_mode.svg +3 -0
- bec_widgets/assets/toolbar_icons/export.svg +9 -0
- bec_widgets/assets/toolbar_icons/fitting_parameters.svg +3 -0
- bec_widgets/assets/toolbar_icons/import.svg +9 -0
- bec_widgets/assets/toolbar_icons/line_axis.svg +3 -0
- bec_widgets/assets/toolbar_icons/photo_library.svg +3 -0
- bec_widgets/assets/toolbar_icons/rectangle_mode.svg +3 -0
- bec_widgets/assets/toolbar_icons/remove.svg +5 -0
- bec_widgets/assets/toolbar_icons/save.svg +3 -0
- bec_widgets/cli/client.py +320 -5
- bec_widgets/cli/server.py +2 -1
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +12 -5
- bec_widgets/examples/plugin_example_pyside/tictactoe.py +1 -0
- bec_widgets/qt_utils/toolbar.py +74 -2
- bec_widgets/widgets/{color_map_selector/color_map_selector.py → colormap_selector/colormap_selector.py} +3 -1
- bec_widgets/widgets/colormap_selector/colormap_selector.pyproject +1 -0
- bec_widgets/widgets/{color_map_selector/color_map_selector_plugin.py → colormap_selector/colormap_selector_plugin.py} +8 -6
- bec_widgets/widgets/{color_map_selector/register_color_map_selector.py → colormap_selector/register_colormap_selector.py} +1 -1
- bec_widgets/widgets/figure/figure.py +12 -0
- bec_widgets/widgets/figure/plots/axis_settings.py +38 -11
- bec_widgets/widgets/figure/plots/image/image.py +1 -0
- bec_widgets/widgets/figure/plots/motor_map/motor_map.py +1 -0
- bec_widgets/widgets/figure/plots/plot_base.py +20 -3
- bec_widgets/widgets/figure/plots/waveform/waveform.py +48 -50
- bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +9 -0
- bec_widgets/widgets/motor_map/bec_motor_map_widget_plugin.py +5 -3
- bec_widgets/widgets/motor_map/motor_map_widget.py +18 -12
- bec_widgets/widgets/waveform/__init__.py +0 -0
- bec_widgets/widgets/waveform/bec_waveform_widget.pyproject +1 -0
- bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py +59 -0
- bec_widgets/widgets/waveform/register_bec_waveform_widget.py +15 -0
- bec_widgets/widgets/waveform/waveform_popups/__init__.py +0 -0
- bec_widgets/widgets/waveform/waveform_popups/curve_dialog/__init__.py +0 -0
- bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py +341 -0
- bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.ui +358 -0
- bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/__init__.py +0 -0
- bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary.ui +127 -0
- bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +69 -0
- bec_widgets/widgets/waveform/waveform_widget.py +579 -0
- {bec_widgets-0.87.1.dist-info → bec_widgets-0.88.1.dist-info}/METADATA +1 -1
- {bec_widgets-0.87.1.dist-info → bec_widgets-0.88.1.dist-info}/RECORD +61 -37
- docs/conf.py +1 -1
- pyproject.toml +1 -1
- tests/unit_tests/test_color_map_selector.py +1 -1
- tests/unit_tests/test_waveform_widget.py +264 -0
- bec_widgets/widgets/color_map_selector/assets/color_map_selector_icon.png +0 -0
- bec_widgets/widgets/color_map_selector/color_map_selector.pyproject +0 -1
- bec_widgets/widgets/motor_map/assets/motor_map.png +0 -0
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_toolbar.py +0 -59
- /bec_widgets/assets/{bec_widgets_icon.png → app_icons/bec_widgets_icon.png} +0 -0
- /bec_widgets/assets/{terminal_icon.png → app_icons/terminal_icon.png} +0 -0
- /bec_widgets/{widgets/motor_map/assets → assets/toolbar_icons}/connection.svg +0 -0
- /bec_widgets/{widgets/motor_map/assets → assets/toolbar_icons}/history.svg +0 -0
- /bec_widgets/{widgets/motor_map/assets → assets/toolbar_icons}/settings.svg +0 -0
- /bec_widgets/widgets/{color_map_selector → colormap_selector}/__init__.py +0 -0
- {bec_widgets-0.87.1.dist-info → bec_widgets-0.88.1.dist-info}/WHEEL +0 -0
- {bec_widgets-0.87.1.dist-info → bec_widgets-0.88.1.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.87.1.dist-info → bec_widgets-0.88.1.dist-info}/licenses/LICENSE +0 -0
bec_widgets/cli/client.py
CHANGED
@@ -19,6 +19,7 @@ class Widgets(str, enum.Enum):
|
|
19
19
|
BECMotorMapWidget = "BECMotorMapWidget"
|
20
20
|
BECQueue = "BECQueue"
|
21
21
|
BECStatusBox = "BECStatusBox"
|
22
|
+
BECWaveformWidget = "BECWaveformWidget"
|
22
23
|
DeviceBox = "DeviceBox"
|
23
24
|
DeviceComboBox = "DeviceComboBox"
|
24
25
|
DeviceLineEdit = "DeviceLineEdit"
|
@@ -184,7 +185,7 @@ class BECDock(RPCBase):
|
|
184
185
|
|
185
186
|
@property
|
186
187
|
@rpc_call
|
187
|
-
def widget_list(self) -> "list[
|
188
|
+
def widget_list(self) -> "list[BECWidget]":
|
188
189
|
"""
|
189
190
|
Get the widgets in the dock.
|
190
191
|
|
@@ -225,13 +226,13 @@ class BECDock(RPCBase):
|
|
225
226
|
@rpc_call
|
226
227
|
def add_widget(
|
227
228
|
self,
|
228
|
-
widget: "
|
229
|
+
widget: "BECWidget | str",
|
229
230
|
row=None,
|
230
231
|
col=0,
|
231
232
|
rowspan=1,
|
232
233
|
colspan=1,
|
233
234
|
shift: "Literal['down', 'up', 'left', 'right']" = "down",
|
234
|
-
) -> "
|
235
|
+
) -> "BECWidget":
|
235
236
|
"""
|
236
237
|
Add a widget to the dock.
|
237
238
|
|
@@ -614,6 +615,12 @@ class BECFigure(RPCBase):
|
|
614
615
|
theme(Literal["dark","light"]): The theme to set for the figure widget.
|
615
616
|
"""
|
616
617
|
|
618
|
+
@rpc_call
|
619
|
+
def export(self):
|
620
|
+
"""
|
621
|
+
Export the plot widget.
|
622
|
+
"""
|
623
|
+
|
617
624
|
@rpc_call
|
618
625
|
def clear_all(self):
|
619
626
|
"""
|
@@ -1096,6 +1103,12 @@ class BECImageShow(RPCBase):
|
|
1096
1103
|
lock(bool): True to lock, False to unlock.
|
1097
1104
|
"""
|
1098
1105
|
|
1106
|
+
@rpc_call
|
1107
|
+
def export(self):
|
1108
|
+
"""
|
1109
|
+
Show the Export Dialog of the plot widget.
|
1110
|
+
"""
|
1111
|
+
|
1099
1112
|
@rpc_call
|
1100
1113
|
def remove(self):
|
1101
1114
|
"""
|
@@ -1204,6 +1217,12 @@ class BECMotorMap(RPCBase):
|
|
1204
1217
|
dict: Data of the motor map.
|
1205
1218
|
"""
|
1206
1219
|
|
1220
|
+
@rpc_call
|
1221
|
+
def export(self):
|
1222
|
+
"""
|
1223
|
+
Show the Export Dialog of the plot widget.
|
1224
|
+
"""
|
1225
|
+
|
1207
1226
|
@rpc_call
|
1208
1227
|
def remove(self):
|
1209
1228
|
"""
|
@@ -1298,6 +1317,12 @@ class BECMotorMapWidget(RPCBase):
|
|
1298
1317
|
Reset the history of the motor map.
|
1299
1318
|
"""
|
1300
1319
|
|
1320
|
+
@rpc_call
|
1321
|
+
def export(self):
|
1322
|
+
"""
|
1323
|
+
Show the export dialog for the motor map.
|
1324
|
+
"""
|
1325
|
+
|
1301
1326
|
|
1302
1327
|
class BECPlotBase(RPCBase):
|
1303
1328
|
@property
|
@@ -1426,6 +1451,12 @@ class BECPlotBase(RPCBase):
|
|
1426
1451
|
lock(bool): True to lock, False to unlock.
|
1427
1452
|
"""
|
1428
1453
|
|
1454
|
+
@rpc_call
|
1455
|
+
def export(self):
|
1456
|
+
"""
|
1457
|
+
Show the Export Dialog of the plot widget.
|
1458
|
+
"""
|
1459
|
+
|
1429
1460
|
@rpc_call
|
1430
1461
|
def remove(self):
|
1431
1462
|
"""
|
@@ -1563,8 +1594,6 @@ class BECWaveform(RPCBase):
|
|
1563
1594
|
y_name(str): Name of the y signal.
|
1564
1595
|
y_entry(str): Entry of the y signal.
|
1565
1596
|
color(str, optional): Color of the curve. Defaults to None.
|
1566
|
-
color_map_z(str): The color map to use for the z-axis.
|
1567
|
-
label(str, optional): Label of the curve. Defaults to None.
|
1568
1597
|
dap(str): The dap model to use for the curve.
|
1569
1598
|
validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
|
1570
1599
|
**kwargs: Additional keyword arguments for the curve configuration.
|
@@ -1756,6 +1785,15 @@ class BECWaveform(RPCBase):
|
|
1756
1785
|
y(bool): Show grid on the y-axis.
|
1757
1786
|
"""
|
1758
1787
|
|
1788
|
+
@rpc_call
|
1789
|
+
def set_colormap(self, colormap: "str | None" = None):
|
1790
|
+
"""
|
1791
|
+
Set the colormap of the plot widget.
|
1792
|
+
|
1793
|
+
Args:
|
1794
|
+
colormap(str, optional): Scale the colors of curves to colormap. If None, use the default color palette.
|
1795
|
+
"""
|
1796
|
+
|
1759
1797
|
@rpc_call
|
1760
1798
|
def lock_aspect_ratio(self, lock):
|
1761
1799
|
"""
|
@@ -1765,6 +1803,12 @@ class BECWaveform(RPCBase):
|
|
1765
1803
|
lock(bool): True to lock, False to unlock.
|
1766
1804
|
"""
|
1767
1805
|
|
1806
|
+
@rpc_call
|
1807
|
+
def export(self):
|
1808
|
+
"""
|
1809
|
+
Show the Export Dialog of the plot widget.
|
1810
|
+
"""
|
1811
|
+
|
1768
1812
|
@rpc_call
|
1769
1813
|
def remove(self):
|
1770
1814
|
"""
|
@@ -1787,6 +1831,277 @@ class BECWaveform(RPCBase):
|
|
1787
1831
|
"""
|
1788
1832
|
|
1789
1833
|
|
1834
|
+
class BECWaveformWidget(RPCBase):
|
1835
|
+
@property
|
1836
|
+
@rpc_call
|
1837
|
+
def curves(self) -> "list[BECCurve]":
|
1838
|
+
"""
|
1839
|
+
Get the curves of the plot widget as a list
|
1840
|
+
Returns:
|
1841
|
+
list: List of curves.
|
1842
|
+
"""
|
1843
|
+
|
1844
|
+
@rpc_call
|
1845
|
+
def plot(
|
1846
|
+
self,
|
1847
|
+
arg1: "list | np.ndarray | str | None" = None,
|
1848
|
+
x: "list | np.ndarray | None" = None,
|
1849
|
+
y: "list | np.ndarray | None" = None,
|
1850
|
+
x_name: "str | None" = None,
|
1851
|
+
y_name: "str | None" = None,
|
1852
|
+
z_name: "str | None" = None,
|
1853
|
+
x_entry: "str | None" = None,
|
1854
|
+
y_entry: "str | None" = None,
|
1855
|
+
z_entry: "str | None" = None,
|
1856
|
+
color: "str | None" = None,
|
1857
|
+
color_map_z: "str | None" = "plasma",
|
1858
|
+
label: "str | None" = None,
|
1859
|
+
validate: "bool" = True,
|
1860
|
+
dap: "str | None" = None,
|
1861
|
+
**kwargs,
|
1862
|
+
) -> "BECCurve":
|
1863
|
+
"""
|
1864
|
+
Plot a curve to the plot widget.
|
1865
|
+
Args:
|
1866
|
+
arg1(list | np.ndarray | str | None): First argument which can be x data(list | np.ndarray), y data(list | np.ndarray), or y_name(str).
|
1867
|
+
x(list | np.ndarray): Custom x data to plot.
|
1868
|
+
y(list | np.ndarray): Custom y data to plot.
|
1869
|
+
x_name(str): The name of the device for the x-axis.
|
1870
|
+
y_name(str): The name of the device for the y-axis.
|
1871
|
+
z_name(str): The name of the device for the z-axis.
|
1872
|
+
x_entry(str): The name of the entry for the x-axis.
|
1873
|
+
y_entry(str): The name of the entry for the y-axis.
|
1874
|
+
z_entry(str): The name of the entry for the z-axis.
|
1875
|
+
color(str): The color of the curve.
|
1876
|
+
color_map_z(str): The color map to use for the z-axis.
|
1877
|
+
label(str): The label of the curve.
|
1878
|
+
validate(bool): If True, validate the device names and entries.
|
1879
|
+
dap(str): The dap model to use for the curve. If not specified, none will be added.
|
1880
|
+
|
1881
|
+
Returns:
|
1882
|
+
BECCurve: The curve object.
|
1883
|
+
"""
|
1884
|
+
|
1885
|
+
@rpc_call
|
1886
|
+
def add_dap(
|
1887
|
+
self,
|
1888
|
+
x_name: "str",
|
1889
|
+
y_name: "str",
|
1890
|
+
x_entry: "str | None" = None,
|
1891
|
+
y_entry: "str | None" = None,
|
1892
|
+
color: "str | None" = None,
|
1893
|
+
dap: "str" = "GaussianModel",
|
1894
|
+
validate_bec: "bool" = True,
|
1895
|
+
**kwargs,
|
1896
|
+
) -> "BECCurve":
|
1897
|
+
"""
|
1898
|
+
Add LMFIT dap model curve to the plot widget.
|
1899
|
+
|
1900
|
+
Args:
|
1901
|
+
x_name(str): Name of the x signal.
|
1902
|
+
x_entry(str): Entry of the x signal.
|
1903
|
+
y_name(str): Name of the y signal.
|
1904
|
+
y_entry(str): Entry of the y signal.
|
1905
|
+
color(str, optional): Color of the curve. Defaults to None.
|
1906
|
+
dap(str): The dap model to use for the curve.
|
1907
|
+
validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
|
1908
|
+
**kwargs: Additional keyword arguments for the curve configuration.
|
1909
|
+
|
1910
|
+
Returns:
|
1911
|
+
BECCurve: The curve object.
|
1912
|
+
"""
|
1913
|
+
|
1914
|
+
@rpc_call
|
1915
|
+
def get_dap_params(self) -> "dict":
|
1916
|
+
"""
|
1917
|
+
Get the DAP parameters of all DAP curves.
|
1918
|
+
|
1919
|
+
Returns:
|
1920
|
+
dict: DAP parameters of all DAP curves.
|
1921
|
+
"""
|
1922
|
+
|
1923
|
+
@rpc_call
|
1924
|
+
def remove_curve(self, *identifiers):
|
1925
|
+
"""
|
1926
|
+
Remove a curve from the plot widget.
|
1927
|
+
|
1928
|
+
Args:
|
1929
|
+
*identifiers: Identifier of the curve to be removed. Can be either an integer (index) or a string (curve_id).
|
1930
|
+
"""
|
1931
|
+
|
1932
|
+
@rpc_call
|
1933
|
+
def scan_history(self, scan_index: "int" = None, scan_id: "str" = None):
|
1934
|
+
"""
|
1935
|
+
Update the scan curves with the data from the scan storage.
|
1936
|
+
Provide only one of scan_id or scan_index.
|
1937
|
+
|
1938
|
+
Args:
|
1939
|
+
scan_id(str, optional): ScanID of the scan to be updated. Defaults to None.
|
1940
|
+
scan_index(int, optional): Index of the scan to be updated. Defaults to None.
|
1941
|
+
"""
|
1942
|
+
|
1943
|
+
@rpc_call
|
1944
|
+
def get_all_data(self, output: "Literal['dict', 'pandas']" = "dict") -> "dict | pd.DataFrame":
|
1945
|
+
"""
|
1946
|
+
Extract all curve data into a dictionary or a pandas DataFrame.
|
1947
|
+
|
1948
|
+
Args:
|
1949
|
+
output (Literal["dict", "pandas"]): Format of the output data.
|
1950
|
+
|
1951
|
+
Returns:
|
1952
|
+
dict | pd.DataFrame: Data of all curves in the specified format.
|
1953
|
+
"""
|
1954
|
+
|
1955
|
+
@rpc_call
|
1956
|
+
def set(self, **kwargs):
|
1957
|
+
"""
|
1958
|
+
Set the properties of the plot widget.
|
1959
|
+
|
1960
|
+
Args:
|
1961
|
+
**kwargs: Keyword arguments for the properties to be set.
|
1962
|
+
|
1963
|
+
Possible properties:
|
1964
|
+
- title: str
|
1965
|
+
- x_label: str
|
1966
|
+
- y_label: str
|
1967
|
+
- x_scale: Literal["linear", "log"]
|
1968
|
+
- y_scale: Literal["linear", "log"]
|
1969
|
+
- x_lim: tuple
|
1970
|
+
- y_lim: tuple
|
1971
|
+
- legend_label_size: int
|
1972
|
+
"""
|
1973
|
+
|
1974
|
+
@rpc_call
|
1975
|
+
def set_x(self, x_name: "str", x_entry: "str | None" = None):
|
1976
|
+
"""
|
1977
|
+
Change the x axis of the plot widget.
|
1978
|
+
|
1979
|
+
Args:
|
1980
|
+
x_name(str): Name of the x signal.
|
1981
|
+
- "best_effort": Use the best effort signal.
|
1982
|
+
- "timestamp": Use the timestamp signal.
|
1983
|
+
- "index": Use the index signal.
|
1984
|
+
- Custom signal name of device from BEC.
|
1985
|
+
x_entry(str): Entry of the x signal.
|
1986
|
+
"""
|
1987
|
+
|
1988
|
+
@rpc_call
|
1989
|
+
def set_title(self, title: "str"):
|
1990
|
+
"""
|
1991
|
+
Set the title of the plot widget.
|
1992
|
+
|
1993
|
+
Args:
|
1994
|
+
title(str): Title of the plot.
|
1995
|
+
"""
|
1996
|
+
|
1997
|
+
@rpc_call
|
1998
|
+
def set_x_label(self, x_label: "str"):
|
1999
|
+
"""
|
2000
|
+
Set the x-axis label of the plot widget.
|
2001
|
+
|
2002
|
+
Args:
|
2003
|
+
x_label(str): Label of the x-axis.
|
2004
|
+
"""
|
2005
|
+
|
2006
|
+
@rpc_call
|
2007
|
+
def set_y_label(self, y_label: "str"):
|
2008
|
+
"""
|
2009
|
+
Set the y-axis label of the plot widget.
|
2010
|
+
|
2011
|
+
Args:
|
2012
|
+
y_label(str): Label of the y-axis.
|
2013
|
+
"""
|
2014
|
+
|
2015
|
+
@rpc_call
|
2016
|
+
def set_x_scale(self, x_scale: "Literal['linear', 'log']"):
|
2017
|
+
"""
|
2018
|
+
Set the scale of the x-axis of the plot widget.
|
2019
|
+
|
2020
|
+
Args:
|
2021
|
+
x_scale(Literal["linear", "log"]): Scale of the x-axis.
|
2022
|
+
"""
|
2023
|
+
|
2024
|
+
@rpc_call
|
2025
|
+
def set_y_scale(self, y_scale: "Literal['linear', 'log']"):
|
2026
|
+
"""
|
2027
|
+
Set the scale of the y-axis of the plot widget.
|
2028
|
+
|
2029
|
+
Args:
|
2030
|
+
y_scale(Literal["linear", "log"]): Scale of the y-axis.
|
2031
|
+
"""
|
2032
|
+
|
2033
|
+
@rpc_call
|
2034
|
+
def set_x_lim(self, x_lim: "tuple"):
|
2035
|
+
"""
|
2036
|
+
Set the limits of the x-axis of the plot widget.
|
2037
|
+
|
2038
|
+
Args:
|
2039
|
+
x_lim(tuple): Limits of the x-axis.
|
2040
|
+
"""
|
2041
|
+
|
2042
|
+
@rpc_call
|
2043
|
+
def set_y_lim(self, y_lim: "tuple"):
|
2044
|
+
"""
|
2045
|
+
Set the limits of the y-axis of the plot widget.
|
2046
|
+
|
2047
|
+
Args:
|
2048
|
+
y_lim(tuple): Limits of the y-axis.
|
2049
|
+
"""
|
2050
|
+
|
2051
|
+
@rpc_call
|
2052
|
+
def set_legend_label_size(self, legend_label_size: "int"):
|
2053
|
+
"""
|
2054
|
+
Set the size of the legend labels of the plot widget.
|
2055
|
+
|
2056
|
+
Args:
|
2057
|
+
legend_label_size(int): Size of the legend labels.
|
2058
|
+
"""
|
2059
|
+
|
2060
|
+
@rpc_call
|
2061
|
+
def set_auto_range(self, enabled: "bool", axis: "str" = "xy"):
|
2062
|
+
"""
|
2063
|
+
Set the auto range of the plot widget.
|
2064
|
+
|
2065
|
+
Args:
|
2066
|
+
enabled(bool): If True, enable the auto range.
|
2067
|
+
axis(str, optional): The axis to enable the auto range.
|
2068
|
+
- "xy": Enable auto range for both x and y axis.
|
2069
|
+
- "x": Enable auto range for x axis.
|
2070
|
+
- "y": Enable auto range for y axis.
|
2071
|
+
"""
|
2072
|
+
|
2073
|
+
@rpc_call
|
2074
|
+
def set_grid(self, x_grid: "bool", y_grid: "bool"):
|
2075
|
+
"""
|
2076
|
+
Set the grid visibility of the plot widget.
|
2077
|
+
|
2078
|
+
Args:
|
2079
|
+
x_grid(bool): Visibility of the x-axis grid.
|
2080
|
+
y_grid(bool): Visibility of the y-axis grid.
|
2081
|
+
"""
|
2082
|
+
|
2083
|
+
@rpc_call
|
2084
|
+
def lock_aspect_ratio(self, lock: "bool"):
|
2085
|
+
"""
|
2086
|
+
Lock the aspect ratio of the plot widget.
|
2087
|
+
|
2088
|
+
Args:
|
2089
|
+
lock(bool): Lock the aspect ratio.
|
2090
|
+
"""
|
2091
|
+
|
2092
|
+
@rpc_call
|
2093
|
+
def export(self):
|
2094
|
+
"""
|
2095
|
+
Show the export dialog for the plot widget.
|
2096
|
+
"""
|
2097
|
+
|
2098
|
+
@rpc_call
|
2099
|
+
def export_to_matplotlib(self):
|
2100
|
+
"""
|
2101
|
+
Export the plot widget to Matplotlib.
|
2102
|
+
"""
|
2103
|
+
|
2104
|
+
|
1790
2105
|
class DeviceBox(RPCBase):
|
1791
2106
|
@property
|
1792
2107
|
@rpc_call
|
bec_widgets/cli/server.py
CHANGED
@@ -202,7 +202,8 @@ def main():
|
|
202
202
|
module_path = os.path.dirname(bec_widgets.__file__)
|
203
203
|
icon = QIcon()
|
204
204
|
icon.addFile(
|
205
|
-
os.path.join(module_path, "assets", "bec_widgets_icon.png"),
|
205
|
+
os.path.join(module_path, "assets", "app_icons", "bec_widgets_icon.png"),
|
206
|
+
size=QSize(48, 48),
|
206
207
|
)
|
207
208
|
app.setWindowIcon(icon)
|
208
209
|
|
@@ -49,8 +49,9 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
49
49
|
"d0": self.d0,
|
50
50
|
"d1": self.d1,
|
51
51
|
"d2": self.d2,
|
52
|
-
"
|
52
|
+
"wave": self.wave,
|
53
53
|
"bar": self.bar,
|
54
|
+
"cm": self.colormap,
|
54
55
|
}
|
55
56
|
)
|
56
57
|
|
@@ -165,12 +166,16 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
|
165
166
|
self.fig1.plot(x_name="samx", y_name="bpm3a")
|
166
167
|
|
167
168
|
self.d2 = self.dock.add_dock(name="dock_2", position="bottom")
|
168
|
-
self.
|
169
|
-
|
170
|
-
self.
|
169
|
+
self.wave = self.d2.add_widget("BECWaveformWidget", row=0, col=0)
|
170
|
+
# self.wave.plot(x_name="samx", y_name="bpm3a")
|
171
|
+
# self.wave.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
|
171
172
|
self.bar = self.d2.add_widget("RingProgressBar", row=0, col=1)
|
172
173
|
self.bar.set_diameter(200)
|
173
174
|
|
175
|
+
self.d3 = self.dock.add_dock(name="dock_3", position="bottom")
|
176
|
+
self.colormap = pg.GradientWidget()
|
177
|
+
self.d3.add_widget(self.colormap, row=0, col=0)
|
178
|
+
|
174
179
|
self.dock.save_state()
|
175
180
|
|
176
181
|
def closeEvent(self, event):
|
@@ -196,7 +201,9 @@ if __name__ == "__main__": # pragma: no cover
|
|
196
201
|
app.setApplicationDisplayName("Jupyter Console")
|
197
202
|
apply_theme("dark")
|
198
203
|
icon = QIcon()
|
199
|
-
icon.addFile(
|
204
|
+
icon.addFile(
|
205
|
+
os.path.join(module_path, "assets", "app_icons", "terminal_icon.png"), size=QSize(48, 48)
|
206
|
+
)
|
200
207
|
app.setWindowIcon(icon)
|
201
208
|
|
202
209
|
bec_dispatcher = BECDispatcher()
|
bec_widgets/qt_utils/toolbar.py
CHANGED
@@ -1,12 +1,35 @@
|
|
1
|
+
# pylint: disable=no-name-in-module
|
2
|
+
import os
|
1
3
|
from abc import ABC, abstractmethod
|
2
4
|
from collections import defaultdict
|
3
5
|
|
4
|
-
# pylint: disable=no-name-in-module
|
5
6
|
from qtpy.QtCore import QSize
|
6
|
-
from qtpy.
|
7
|
+
from qtpy.QtGui import QAction, QIcon
|
8
|
+
from qtpy.QtWidgets import QHBoxLayout, QLabel, QToolBar, QToolButton, QWidget
|
9
|
+
|
10
|
+
import bec_widgets
|
11
|
+
|
12
|
+
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
7
13
|
|
8
14
|
|
9
15
|
class ToolBarAction(ABC):
|
16
|
+
"""
|
17
|
+
Abstract base class for toolbar actions.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
icon_path (str, optional): The name of the icon file from `assets/toolbar_icons`. Defaults to None.
|
21
|
+
tooltip (bool, optional): The tooltip for the action. Defaults to None.
|
22
|
+
checkable (bool, optional): Whether the action is checkable. Defaults to False.
|
23
|
+
"""
|
24
|
+
|
25
|
+
def __init__(self, icon_path: str = None, tooltip: str = None, checkable: bool = False):
|
26
|
+
self.icon_path = (
|
27
|
+
os.path.join(MODULE_PATH, "assets", "toolbar_icons", icon_path) if icon_path else None
|
28
|
+
)
|
29
|
+
self.tooltip = tooltip
|
30
|
+
self.checkable = checkable
|
31
|
+
self.action = None
|
32
|
+
|
10
33
|
@abstractmethod
|
11
34
|
def add_to_toolbar(self, toolbar: QToolBar, target: QWidget):
|
12
35
|
"""Adds an action or widget to a toolbar.
|
@@ -26,6 +49,55 @@ class SeparatorAction(ToolBarAction):
|
|
26
49
|
toolbar.addWidget(self.separator)
|
27
50
|
|
28
51
|
|
52
|
+
class IconAction(ToolBarAction):
|
53
|
+
"""
|
54
|
+
Action with an icon for the toolbar.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
icon_path (str): The path to the icon file.
|
58
|
+
tooltip (str): The tooltip for the action.
|
59
|
+
checkable (bool, optional): Whether the action is checkable. Defaults to False.
|
60
|
+
"""
|
61
|
+
|
62
|
+
def __init__(self, icon_path: str = None, tooltip: str = None, checkable: bool = False):
|
63
|
+
super().__init__(icon_path, tooltip, checkable)
|
64
|
+
|
65
|
+
def add_to_toolbar(self, toolbar: QToolBar, target: QWidget):
|
66
|
+
icon = QIcon()
|
67
|
+
icon.addFile(self.icon_path, size=QSize(20, 20))
|
68
|
+
self.action = QAction(icon, self.tooltip, target)
|
69
|
+
self.action.setCheckable(self.checkable)
|
70
|
+
toolbar.addAction(self.action)
|
71
|
+
|
72
|
+
|
73
|
+
class DeviceSelectionAction(ToolBarAction):
|
74
|
+
"""
|
75
|
+
Action for selecting a device in a combobox.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
label (str): The label for the combobox.
|
79
|
+
device_combobox (DeviceComboBox): The combobox for selecting the device.
|
80
|
+
|
81
|
+
"""
|
82
|
+
|
83
|
+
def __init__(self, label: str, device_combobox):
|
84
|
+
super().__init__()
|
85
|
+
self.label = label
|
86
|
+
self.device_combobox = device_combobox
|
87
|
+
self.device_combobox.currentIndexChanged.connect(lambda: self.set_combobox_style("#ffa700"))
|
88
|
+
|
89
|
+
def add_to_toolbar(self, toolbar, target):
|
90
|
+
widget = QWidget()
|
91
|
+
layout = QHBoxLayout(widget)
|
92
|
+
label = QLabel(f"{self.label}")
|
93
|
+
layout.addWidget(label)
|
94
|
+
layout.addWidget(self.device_combobox)
|
95
|
+
toolbar.addWidget(widget)
|
96
|
+
|
97
|
+
def set_combobox_style(self, color: str):
|
98
|
+
self.device_combobox.setStyleSheet(f"QComboBox {{ background-color: {color}; }}")
|
99
|
+
|
100
|
+
|
29
101
|
class ModularToolBar(QToolBar):
|
30
102
|
"""Modular toolbar with optional automatic initialization.
|
31
103
|
Args:
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import pyqtgraph as pg
|
2
4
|
from qtpy.QtCore import Property, Signal, Slot
|
3
5
|
from qtpy.QtGui import QColor, QFontMetrics, QImage
|
@@ -46,7 +48,7 @@ class ColormapSelector(QWidget):
|
|
46
48
|
colormap_changed_signal = Signal(str)
|
47
49
|
|
48
50
|
def __init__(self, parent=None, default_colormaps=None):
|
49
|
-
super().__init__(parent)
|
51
|
+
super().__init__(parent=parent)
|
50
52
|
self._colormaps = []
|
51
53
|
self.initUI(default_colormaps)
|
52
54
|
|
@@ -0,0 +1 @@
|
|
1
|
+
{'files': ['colormap_selector.py']}
|
@@ -5,15 +5,18 @@ import os
|
|
5
5
|
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
6
6
|
from qtpy.QtGui import QIcon
|
7
7
|
|
8
|
-
|
8
|
+
import bec_widgets
|
9
|
+
from bec_widgets.widgets.colormap_selector.colormap_selector import ColormapSelector
|
9
10
|
|
10
11
|
DOM_XML = """
|
11
12
|
<ui language='c++'>
|
12
|
-
<widget class='ColormapSelector' name='
|
13
|
+
<widget class='ColormapSelector' name='colormap_selector'>
|
13
14
|
</widget>
|
14
15
|
</ui>
|
15
16
|
"""
|
16
17
|
|
18
|
+
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
19
|
+
|
17
20
|
|
18
21
|
class ColormapSelectorPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
19
22
|
def __init__(self):
|
@@ -31,12 +34,11 @@ class ColormapSelectorPlugin(QDesignerCustomWidgetInterface): # pragma: no cove
|
|
31
34
|
return "BEC Buttons"
|
32
35
|
|
33
36
|
def icon(self):
|
34
|
-
|
35
|
-
icon_path = os.path.join(current_path, "assets", "color_map_selector_icon.png")
|
37
|
+
icon_path = os.path.join(MODULE_PATH, "assets", "designer_icons", "colormap_selector.png")
|
36
38
|
return QIcon(icon_path)
|
37
39
|
|
38
40
|
def includeFile(self):
|
39
|
-
return "
|
41
|
+
return "colormap_selector"
|
40
42
|
|
41
43
|
def initialize(self, form_editor):
|
42
44
|
self._form_editor = form_editor
|
@@ -51,7 +53,7 @@ class ColormapSelectorPlugin(QDesignerCustomWidgetInterface): # pragma: no cove
|
|
51
53
|
return "ColormapSelector"
|
52
54
|
|
53
55
|
def toolTip(self):
|
54
|
-
return "
|
56
|
+
return ""
|
55
57
|
|
56
58
|
def whatsThis(self):
|
57
59
|
return self.toolTip()
|
@@ -6,7 +6,7 @@ def main(): # pragma: no cover
|
|
6
6
|
return
|
7
7
|
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
8
8
|
|
9
|
-
from bec_widgets.widgets.
|
9
|
+
from bec_widgets.widgets.colormap_selector.colormap_selector_plugin import (
|
10
10
|
ColormapSelectorPlugin,
|
11
11
|
)
|
12
12
|
|
@@ -122,6 +122,7 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
|
|
122
122
|
"remove",
|
123
123
|
"change_layout",
|
124
124
|
"change_theme",
|
125
|
+
"export",
|
125
126
|
"clear_all",
|
126
127
|
"widget_list",
|
127
128
|
]
|
@@ -228,6 +229,17 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
|
|
228
229
|
"""
|
229
230
|
self._widgets = value
|
230
231
|
|
232
|
+
def export(self):
|
233
|
+
"""Export the plot widget."""
|
234
|
+
try:
|
235
|
+
plot_item = self.widget_list[0]
|
236
|
+
except:
|
237
|
+
raise ValueError("No plot widget available to export.")
|
238
|
+
|
239
|
+
scene = plot_item.scene()
|
240
|
+
scene.contextMenuItem = plot_item
|
241
|
+
scene.showExportDialog()
|
242
|
+
|
231
243
|
@typechecked
|
232
244
|
def plot(
|
233
245
|
self,
|