bec-widgets 0.91.0__py3-none-any.whl → 0.92.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.
- .gitlab-ci.yml +12 -8
- CHANGELOG.md +40 -44
- PKG-INFO +1 -1
- bec_widgets/assets/app_icons/BEC-Dark.png +0 -0
- bec_widgets/examples/general_app/__init__.py +0 -0
- bec_widgets/examples/general_app/general_app.py +92 -0
- bec_widgets/examples/general_app/general_app.ui +262 -0
- bec_widgets/examples/general_app/web_links.py +15 -0
- bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +2 -1
- bec_widgets/qt_utils/error_popups.py +19 -30
- bec_widgets/qt_utils/settings_dialog.py +2 -1
- bec_widgets/utils/bec_connector.py +1 -1
- bec_widgets/widgets/console/console.py +3 -2
- bec_widgets/widgets/device_combobox/device_combobox.py +1 -1
- bec_widgets/widgets/dock/dock.py +63 -2
- bec_widgets/widgets/figure/figure.py +10 -10
- bec_widgets/widgets/figure/plots/axis_settings.py +1 -1
- bec_widgets/widgets/figure/plots/image/image.py +17 -17
- bec_widgets/widgets/figure/plots/motor_map/motor_map.py +2 -2
- bec_widgets/widgets/figure/plots/waveform/waveform.py +15 -15
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py +1 -1
- bec_widgets/widgets/stop_button/stop_button.py +1 -1
- bec_widgets/widgets/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +1 -1
- {bec_widgets-0.91.0.dist-info → bec_widgets-0.92.1.dist-info}/METADATA +1 -1
- {bec_widgets-0.91.0.dist-info → bec_widgets-0.92.1.dist-info}/RECORD +34 -29
- pyproject.toml +1 -1
- tests/end-2-end/test_bec_dock_rpc_e2e.py +1 -1
- tests/end-2-end/test_bec_figure_rpc_e2e.py +1 -1
- tests/unit_tests/conftest.py +12 -1
- tests/unit_tests/test_bec_connector.py +1 -1
- tests/unit_tests/test_bec_image.py +3 -3
- {bec_widgets-0.91.0.dist-info → bec_widgets-0.92.1.dist-info}/WHEEL +0 -0
- {bec_widgets-0.91.0.dist-info → bec_widgets-0.92.1.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.91.0.dist-info → bec_widgets-0.92.1.dist-info}/licenses/LICENSE +0 -0
.gitlab-ci.yml
CHANGED
@@ -43,13 +43,20 @@ stages:
|
|
43
43
|
- export QTWEBENGINE_DISABLE_SANDBOX=1
|
44
44
|
|
45
45
|
.clone-repos: &clone-repos
|
46
|
+
- echo -e "\033[35;1m Using branch $BEC_CORE_BRANCH of BEC CORE \033[0;m";
|
46
47
|
- git clone --branch $BEC_CORE_BRANCH https://gitlab.psi.ch/bec/bec.git
|
48
|
+
- echo -e "\033[35;1m Using branch $OPHYD_DEVICES_BRANCH of OPHYD_DEVICES \033[0;m";
|
47
49
|
- git clone --branch $OPHYD_DEVICES_BRANCH https://gitlab.psi.ch/bec/ophyd_devices.git
|
48
50
|
- export OHPYD_DEVICES_PATH=$PWD/ophyd_devices
|
49
51
|
|
52
|
+
.install-repos: &install-repos
|
53
|
+
- pip install -e ./ophyd_devices
|
54
|
+
- pip install -e ./bec/bec_lib[dev]
|
55
|
+
- pip install -e ./bec/bec_ipython_client
|
56
|
+
|
50
57
|
.install-os-packages: &install-os-packages
|
51
58
|
- apt-get update
|
52
|
-
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3
|
59
|
+
- apt-get install -y libgl1-mesa-glx libegl1-mesa x11-utils libxkbcommon-x11-0 libdbus-1-3 xvfb
|
53
60
|
- *install-qt-webengine-deps
|
54
61
|
|
55
62
|
before_script:
|
@@ -131,8 +138,7 @@ tests:
|
|
131
138
|
script:
|
132
139
|
- *clone-repos
|
133
140
|
- *install-os-packages
|
134
|
-
-
|
135
|
-
- pip install -e ./bec/bec_ipython_client
|
141
|
+
- *install-repos
|
136
142
|
- pip install -e .[dev,pyqt6]
|
137
143
|
- coverage run --source=./bec_widgets -m pytest -v --junitxml=report.xml --random-order --full-trace ./tests/unit_tests
|
138
144
|
- coverage report
|
@@ -169,8 +175,7 @@ test-matrix:
|
|
169
175
|
script:
|
170
176
|
- *clone-repos
|
171
177
|
- *install-os-packages
|
172
|
-
-
|
173
|
-
- pip install -e ./bec/bec_ipython_client
|
178
|
+
- *install-repos
|
174
179
|
- pip install -e .[dev,$QT_PCKG]
|
175
180
|
- pytest -v --junitxml=report.xml --random-order ./tests/unit_tests
|
176
181
|
allow_failure: true
|
@@ -195,10 +200,9 @@ end-2-end-conda:
|
|
195
200
|
|
196
201
|
- cd ./bec
|
197
202
|
- source ./bin/install_bec_dev.sh -t
|
198
|
-
|
199
|
-
- pip install -e ./bec_lib[dev]
|
200
|
-
- pip install -e ./bec_ipython_client[dev]
|
201
203
|
- cd ../
|
204
|
+
- pip install -e ./ophyd_devices
|
205
|
+
|
202
206
|
- pip install -e .[dev,pyqt6]
|
203
207
|
- cd ./tests/end-2-end
|
204
208
|
- pytest -v --start-servers --flush-redis --random-order
|
CHANGELOG.md
CHANGED
@@ -1,5 +1,45 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v0.92.1 (2024-07-28)
|
4
|
+
|
5
|
+
### Build
|
6
|
+
|
7
|
+
* build(ci): install ophyd_devices in editable mode for pipelines ([`06205e0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/06205e07903d93accf40abab153f440059f236ed))
|
8
|
+
|
9
|
+
### Fix
|
10
|
+
|
11
|
+
* fix: use SafeSlot instead of Slot ([`bc1e239`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bc1e23944cc0e5a861e3d0b4dc5b4ac6292d5269))
|
12
|
+
|
13
|
+
* fix: linting ([`a3fe205`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a3fe20500ae2ac03dcde07432f7e21ce5262ce46))
|
14
|
+
|
15
|
+
* fix: always add a QApplication for tests ([`61a4e32`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/61a4e32deb337ed27f2f43358b88b7266413b58e))
|
16
|
+
|
17
|
+
* fix: add xvfb to draw offscreen ([`3d681f7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3d681f77e144e74138fc5fa65630004d7c166878))
|
18
|
+
|
19
|
+
* fix: reset ErrorPopup singleton between tests ([`5a9ccfd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5a9ccfd1f6d2aacd5d86c1a34f74163b272d1ae4))
|
20
|
+
|
21
|
+
* fix: metaclass + QObject segfaults PyQt(cpp bindings) ([`fc57b7a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fc57b7a1262031a2df9e6a99493db87e766b779a))
|
22
|
+
|
23
|
+
### Refactor
|
24
|
+
|
25
|
+
* refactor: renamed DeviceMonitor2DMessage ([`4be6fd6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4be6fd6b83ea1048f16310f7d2bbe777b13b245e))
|
26
|
+
|
27
|
+
* refactor: rename device_monitor to device_monitor_2d ([`714e1e1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/714e1e139e0033d2725fefb636c419ca137a68c6))
|
28
|
+
|
29
|
+
## v0.92.0 (2024-07-24)
|
30
|
+
|
31
|
+
### Feature
|
32
|
+
|
33
|
+
* feat(dock): dock style sheets updated ([`8ca60d5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8ca60d54b3cfa621172ce097fc1ba514c47ebac7))
|
34
|
+
|
35
|
+
* feat(general_gui): general gui added ([`5696c99`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5696c993dc1c0da40ff3e99f754c246cc017ea32))
|
36
|
+
|
37
|
+
### Fix
|
38
|
+
|
39
|
+
* fix(dock): custom label can be created closable ([`4457ef2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4457ef2147e21b856c9dcaf63c81ba98002dcaf1))
|
40
|
+
|
41
|
+
* fix(device_combobox): set minimum size to 125px ([`1206e15`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1206e153094cd8505badf69a1461572a76b4c5ad))
|
42
|
+
|
3
43
|
## v0.91.0 (2024-07-23)
|
4
44
|
|
5
45
|
### Feature
|
@@ -88,20 +128,6 @@ This reverts commit 3798714369adf4023f833b7749d2f46a0ec74eee ([`fd6ae91`](https:
|
|
88
128
|
|
89
129
|
* feat(waveform_widget): dap parameter window ([`1e551d6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1e551d6e9696f79ea2e0a179d13a4fc6c2a128b2))
|
90
130
|
|
91
|
-
* feat(waveform): export to matplotlib window of current scene ([`8d93405`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8d9340539967b06b1e15f21a2106a39d5c740f31))
|
92
|
-
|
93
|
-
* feat(figure): export dialog can be launched from CLI and from toolbar ([`6ff6111`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6ff611109153b9412dce37c527b19e839d99bba7))
|
94
|
-
|
95
|
-
* feat(waveform_widget): added error handle utility ([`a8ff1d4`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a8ff1d4cd09cae5eaeb4bd0ea90fdd102e32f3a3))
|
96
|
-
|
97
|
-
* feat(curve_dialog): add DAP functionality ([`e830565`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e8305652fde384da037242cf8f7e3606f22bcfb6))
|
98
|
-
|
99
|
-
* feat(curve_dialog): curves can be added ([`c926a75`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c926a75a7927d672c044ea8f68771209ae5accc6))
|
100
|
-
|
101
|
-
* feat(waveform_widget): BECWaveformWidget toolbar added import/export config ([`fa9b171`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fa9b17191ddbb4043a658dae9aa0801e1dc22b84))
|
102
|
-
|
103
|
-
* feat(waveform_widget): BECWaveformWidget added with toolbar ([`755b394`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/755b394c1c4d7c443c442d89c630d08ce5415554))
|
104
|
-
|
105
131
|
### Fix
|
106
132
|
|
107
133
|
* fix(waveform_widget): plot API unified with BECFigure ([`2c8764a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2c8764a27de89b39b717032b58465e120ec57fbc))
|
@@ -114,36 +140,6 @@ This reverts commit 3798714369adf4023f833b7749d2f46a0ec74eee ([`fd6ae91`](https:
|
|
114
140
|
|
115
141
|
* fix(waveform_widget): use @SafeSlot decorator for automatic error message ([`8e588d7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8e588d79c86e950f6915e89c08fa9415c4bd8033))
|
116
142
|
|
117
|
-
* fix(waveform): colormaps of curves can be changed and normalised
|
118
|
-
|
119
|
-
feat(waveform): colormap can be changed from curve dialog
|
120
|
-
|
121
|
-
fix(curve_dialog): default dialog parameters fixed
|
122
|
-
|
123
|
-
curve Dialog colormap WIP ([`33495cf`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/33495cfe03b363f18db61d8af2983f49027b7a43))
|
124
|
-
|
125
|
-
* fix(waveform_widget): adapted for changes from improved scan logic from waveform widget ([`8ac35d7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8ac35d7280b1ff007c10612228d163cc0c5d1a99))
|
126
|
-
|
127
|
-
### Refactor
|
128
|
-
|
129
|
-
* refactor(icons): icons moved to the assets directory ([`a8b6ef2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a8b6ef20cccae87515b10f054d0ed5b10e152769))
|
130
|
-
|
131
|
-
* refactor(waveform_widget): removed PYSIDE6 check ([`47fcb9e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/47fcb9ebfe35ae600cced95a1edc68f6f6e37a04))
|
132
|
-
|
133
143
|
### Test
|
134
144
|
|
135
145
|
* test(waveform_widget): test added ([`8d764e2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8d764e2d46a1e017dadc3c4630648c1ca708afc2))
|
136
|
-
|
137
|
-
## v0.87.1 (2024-07-18)
|
138
|
-
|
139
|
-
### Fix
|
140
|
-
|
141
|
-
* fix(dock): added hasattr to cleanup method for widgets ([`d75c55b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d75c55b2b1ccf156fb789c7813f1c5bdf256f860))
|
142
|
-
|
143
|
-
* fix: add missing close() call, ensure jupyter console client.shutdown() is called in closeEvent ([`e52ee26`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e52ee2604cb35096f1bd833ca9516d8a34197d35))
|
144
|
-
|
145
|
-
### Refactor
|
146
|
-
|
147
|
-
* refactor: BECWidget is a mixin based on BECConnector, for each QWidget in BEC
|
148
|
-
|
149
|
-
Handles closeEvent() and RPC registering/unregistering ([`c7feb69`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c7feb6952d590b569f7b0cba3b019a9af0ce0c93))
|
PKG-INFO
CHANGED
Binary file
|
File without changes
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
|
4
|
+
from qtpy.QtCore import QSize
|
5
|
+
from qtpy.QtGui import QActionGroup, QIcon
|
6
|
+
from qtpy.QtWidgets import QApplication, QMainWindow, QStyle
|
7
|
+
|
8
|
+
import bec_widgets
|
9
|
+
from bec_widgets.examples.general_app.web_links import BECWebLinksMixin
|
10
|
+
from bec_widgets.utils.colors import apply_theme
|
11
|
+
from bec_widgets.utils.ui_loader import UILoader
|
12
|
+
|
13
|
+
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
14
|
+
|
15
|
+
|
16
|
+
class BECGeneralApp(QMainWindow):
|
17
|
+
def __init__(self, parent=None):
|
18
|
+
super(BECGeneralApp, self).__init__(parent)
|
19
|
+
ui_file_path = os.path.join(os.path.dirname(__file__), "general_app.ui")
|
20
|
+
self.load_ui(ui_file_path)
|
21
|
+
|
22
|
+
self.resize(1280, 720)
|
23
|
+
|
24
|
+
self.ini_ui()
|
25
|
+
|
26
|
+
def ini_ui(self):
|
27
|
+
self._setup_icons()
|
28
|
+
self._hook_menubar_docs()
|
29
|
+
self._hook_theme_bar()
|
30
|
+
|
31
|
+
def load_ui(self, ui_file):
|
32
|
+
loader = UILoader(self)
|
33
|
+
self.ui = loader.loader(ui_file)
|
34
|
+
self.setCentralWidget(self.ui)
|
35
|
+
|
36
|
+
def _hook_menubar_docs(self):
|
37
|
+
# BEC Docs
|
38
|
+
self.ui.action_BEC_docs.triggered.connect(BECWebLinksMixin.open_bec_docs)
|
39
|
+
# BEC Widgets Docs
|
40
|
+
self.ui.action_BEC_widgets_docs.triggered.connect(BECWebLinksMixin.open_bec_widgets_docs)
|
41
|
+
# Bug report
|
42
|
+
self.ui.action_bug_report.triggered.connect(BECWebLinksMixin.open_bec_bug_report)
|
43
|
+
|
44
|
+
def change_theme(self, theme):
|
45
|
+
apply_theme(theme)
|
46
|
+
|
47
|
+
def _setup_icons(self):
|
48
|
+
help_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion)
|
49
|
+
bug_icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxInformation)
|
50
|
+
computer_icon = QIcon.fromTheme("computer")
|
51
|
+
widget_icon = QIcon(os.path.join(MODULE_PATH, "assets", "designer_icons", "dock_area.png"))
|
52
|
+
|
53
|
+
self.ui.action_BEC_docs.setIcon(help_icon)
|
54
|
+
self.ui.action_BEC_widgets_docs.setIcon(help_icon)
|
55
|
+
self.ui.action_bug_report.setIcon(bug_icon)
|
56
|
+
|
57
|
+
self.ui.central_tab.setTabIcon(0, widget_icon)
|
58
|
+
self.ui.central_tab.setTabIcon(1, computer_icon)
|
59
|
+
|
60
|
+
def _hook_theme_bar(self):
|
61
|
+
self.ui.action_light.setCheckable(True)
|
62
|
+
self.ui.action_dark.setCheckable(True)
|
63
|
+
|
64
|
+
# Create an action group to make sure only one can be checked at a time
|
65
|
+
theme_group = QActionGroup(self)
|
66
|
+
theme_group.addAction(self.ui.action_light)
|
67
|
+
theme_group.addAction(self.ui.action_dark)
|
68
|
+
theme_group.setExclusive(True)
|
69
|
+
|
70
|
+
# Connect the actions to the theme change method
|
71
|
+
|
72
|
+
self.ui.action_light.triggered.connect(lambda: self.change_theme("light"))
|
73
|
+
self.ui.action_dark.triggered.connect(lambda: self.change_theme("dark"))
|
74
|
+
|
75
|
+
self.ui.action_dark.trigger()
|
76
|
+
|
77
|
+
|
78
|
+
def main(): # pragma: no cover
|
79
|
+
|
80
|
+
app = QApplication(sys.argv)
|
81
|
+
icon = QIcon()
|
82
|
+
icon.addFile(
|
83
|
+
os.path.join(MODULE_PATH, "assets", "app_icons", "BEC-Dark.png"), size=QSize(48, 48)
|
84
|
+
)
|
85
|
+
app.setWindowIcon(icon)
|
86
|
+
main_window = BECGeneralApp()
|
87
|
+
main_window.show()
|
88
|
+
sys.exit(app.exec_())
|
89
|
+
|
90
|
+
|
91
|
+
if __name__ == "__main__": # pragma: no cover
|
92
|
+
main()
|
@@ -0,0 +1,262 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<ui version="4.0">
|
3
|
+
<class>MainWindow</class>
|
4
|
+
<widget class="QMainWindow" name="MainWindow">
|
5
|
+
<property name="geometry">
|
6
|
+
<rect>
|
7
|
+
<x>0</x>
|
8
|
+
<y>0</y>
|
9
|
+
<width>1718</width>
|
10
|
+
<height>1139</height>
|
11
|
+
</rect>
|
12
|
+
</property>
|
13
|
+
<property name="windowTitle">
|
14
|
+
<string>MainWindow</string>
|
15
|
+
</property>
|
16
|
+
<property name="tabShape">
|
17
|
+
<enum>QTabWidget::TabShape::Rounded</enum>
|
18
|
+
</property>
|
19
|
+
<widget class="QWidget" name="centralwidget">
|
20
|
+
<layout class="QVBoxLayout" name="verticalLayout_3">
|
21
|
+
<item>
|
22
|
+
<widget class="QTabWidget" name="central_tab">
|
23
|
+
<property name="currentIndex">
|
24
|
+
<number>0</number>
|
25
|
+
</property>
|
26
|
+
<widget class="QWidget" name="dock_area_tab">
|
27
|
+
<attribute name="title">
|
28
|
+
<string>Dock Area</string>
|
29
|
+
</attribute>
|
30
|
+
<layout class="QVBoxLayout" name="verticalLayout">
|
31
|
+
<property name="leftMargin">
|
32
|
+
<number>2</number>
|
33
|
+
</property>
|
34
|
+
<property name="topMargin">
|
35
|
+
<number>1</number>
|
36
|
+
</property>
|
37
|
+
<property name="rightMargin">
|
38
|
+
<number>2</number>
|
39
|
+
</property>
|
40
|
+
<property name="bottomMargin">
|
41
|
+
<number>2</number>
|
42
|
+
</property>
|
43
|
+
<item>
|
44
|
+
<widget class="BECDockArea" name="dock_area"/>
|
45
|
+
</item>
|
46
|
+
</layout>
|
47
|
+
</widget>
|
48
|
+
<widget class="QWidget" name="vscode_tab">
|
49
|
+
<attribute name="icon">
|
50
|
+
<iconset theme="QIcon::ThemeIcon::Computer"/>
|
51
|
+
</attribute>
|
52
|
+
<attribute name="title">
|
53
|
+
<string>Visual Studio Code</string>
|
54
|
+
</attribute>
|
55
|
+
<layout class="QVBoxLayout" name="verticalLayout_2">
|
56
|
+
<property name="leftMargin">
|
57
|
+
<number>2</number>
|
58
|
+
</property>
|
59
|
+
<property name="topMargin">
|
60
|
+
<number>1</number>
|
61
|
+
</property>
|
62
|
+
<property name="rightMargin">
|
63
|
+
<number>2</number>
|
64
|
+
</property>
|
65
|
+
<property name="bottomMargin">
|
66
|
+
<number>2</number>
|
67
|
+
</property>
|
68
|
+
<item>
|
69
|
+
<widget class="VSCodeEditor" name="vscode"/>
|
70
|
+
</item>
|
71
|
+
</layout>
|
72
|
+
</widget>
|
73
|
+
</widget>
|
74
|
+
</item>
|
75
|
+
</layout>
|
76
|
+
</widget>
|
77
|
+
<widget class="QMenuBar" name="menubar">
|
78
|
+
<property name="geometry">
|
79
|
+
<rect>
|
80
|
+
<x>0</x>
|
81
|
+
<y>0</y>
|
82
|
+
<width>1718</width>
|
83
|
+
<height>31</height>
|
84
|
+
</rect>
|
85
|
+
</property>
|
86
|
+
<widget class="QMenu" name="menuHelp">
|
87
|
+
<property name="title">
|
88
|
+
<string>Help</string>
|
89
|
+
</property>
|
90
|
+
<addaction name="action_BEC_docs"/>
|
91
|
+
<addaction name="action_BEC_widgets_docs"/>
|
92
|
+
<addaction name="action_bug_report"/>
|
93
|
+
</widget>
|
94
|
+
<widget class="QMenu" name="menuTheme">
|
95
|
+
<property name="title">
|
96
|
+
<string>Theme</string>
|
97
|
+
</property>
|
98
|
+
<addaction name="action_light"/>
|
99
|
+
<addaction name="action_dark"/>
|
100
|
+
</widget>
|
101
|
+
<addaction name="menuTheme"/>
|
102
|
+
<addaction name="menuHelp"/>
|
103
|
+
</widget>
|
104
|
+
<widget class="QStatusBar" name="statusbar"/>
|
105
|
+
<widget class="QDockWidget" name="dock_scan_control">
|
106
|
+
<property name="windowTitle">
|
107
|
+
<string>Scan Control</string>
|
108
|
+
</property>
|
109
|
+
<attribute name="dockWidgetArea">
|
110
|
+
<number>2</number>
|
111
|
+
</attribute>
|
112
|
+
<widget class="QWidget" name="dockWidgetContents_2">
|
113
|
+
<layout class="QVBoxLayout" name="verticalLayout_4">
|
114
|
+
<item>
|
115
|
+
<widget class="ScanControl" name="scan_control"/>
|
116
|
+
</item>
|
117
|
+
</layout>
|
118
|
+
</widget>
|
119
|
+
</widget>
|
120
|
+
<widget class="QDockWidget" name="dock_status_2">
|
121
|
+
<property name="windowTitle">
|
122
|
+
<string>BEC Service Status</string>
|
123
|
+
</property>
|
124
|
+
<attribute name="dockWidgetArea">
|
125
|
+
<number>2</number>
|
126
|
+
</attribute>
|
127
|
+
<widget class="QWidget" name="dockWidgetContents_3">
|
128
|
+
<layout class="QVBoxLayout" name="verticalLayout_5">
|
129
|
+
<property name="leftMargin">
|
130
|
+
<number>0</number>
|
131
|
+
</property>
|
132
|
+
<property name="topMargin">
|
133
|
+
<number>0</number>
|
134
|
+
</property>
|
135
|
+
<property name="rightMargin">
|
136
|
+
<number>0</number>
|
137
|
+
</property>
|
138
|
+
<property name="bottomMargin">
|
139
|
+
<number>0</number>
|
140
|
+
</property>
|
141
|
+
<item>
|
142
|
+
<widget class="BECStatusBox" name="bec_status_box_2"/>
|
143
|
+
</item>
|
144
|
+
</layout>
|
145
|
+
</widget>
|
146
|
+
</widget>
|
147
|
+
<widget class="QDockWidget" name="dock_queue">
|
148
|
+
<property name="windowTitle">
|
149
|
+
<string>Scan Queue</string>
|
150
|
+
</property>
|
151
|
+
<attribute name="dockWidgetArea">
|
152
|
+
<number>2</number>
|
153
|
+
</attribute>
|
154
|
+
<widget class="QWidget" name="dockWidgetContents_4">
|
155
|
+
<layout class="QVBoxLayout" name="verticalLayout_6">
|
156
|
+
<property name="leftMargin">
|
157
|
+
<number>0</number>
|
158
|
+
</property>
|
159
|
+
<property name="topMargin">
|
160
|
+
<number>0</number>
|
161
|
+
</property>
|
162
|
+
<property name="rightMargin">
|
163
|
+
<number>0</number>
|
164
|
+
</property>
|
165
|
+
<property name="bottomMargin">
|
166
|
+
<number>0</number>
|
167
|
+
</property>
|
168
|
+
<item>
|
169
|
+
<widget class="BECQueue" name="bec_queue">
|
170
|
+
<row/>
|
171
|
+
<column/>
|
172
|
+
<column/>
|
173
|
+
<column/>
|
174
|
+
<item row="0" column="0"/>
|
175
|
+
<item row="0" column="1"/>
|
176
|
+
<item row="0" column="2"/>
|
177
|
+
</widget>
|
178
|
+
</item>
|
179
|
+
</layout>
|
180
|
+
</widget>
|
181
|
+
</widget>
|
182
|
+
<action name="action_BEC_docs">
|
183
|
+
<property name="icon">
|
184
|
+
<iconset theme="QIcon::ThemeIcon::DialogQuestion"/>
|
185
|
+
</property>
|
186
|
+
<property name="text">
|
187
|
+
<string>BEC Docs</string>
|
188
|
+
</property>
|
189
|
+
</action>
|
190
|
+
<action name="action_BEC_widgets_docs">
|
191
|
+
<property name="icon">
|
192
|
+
<iconset theme="QIcon::ThemeIcon::DialogQuestion"/>
|
193
|
+
</property>
|
194
|
+
<property name="text">
|
195
|
+
<string>BEC Widgets Docs</string>
|
196
|
+
</property>
|
197
|
+
</action>
|
198
|
+
<action name="action_bug_report">
|
199
|
+
<property name="icon">
|
200
|
+
<iconset theme="QIcon::ThemeIcon::DialogError"/>
|
201
|
+
</property>
|
202
|
+
<property name="text">
|
203
|
+
<string>Bug Report</string>
|
204
|
+
</property>
|
205
|
+
</action>
|
206
|
+
<action name="action_light">
|
207
|
+
<property name="checkable">
|
208
|
+
<bool>true</bool>
|
209
|
+
</property>
|
210
|
+
<property name="text">
|
211
|
+
<string>Light</string>
|
212
|
+
</property>
|
213
|
+
</action>
|
214
|
+
<action name="action_dark">
|
215
|
+
<property name="checkable">
|
216
|
+
<bool>true</bool>
|
217
|
+
</property>
|
218
|
+
<property name="text">
|
219
|
+
<string>Dark</string>
|
220
|
+
</property>
|
221
|
+
</action>
|
222
|
+
</widget>
|
223
|
+
<customwidgets>
|
224
|
+
<customwidget>
|
225
|
+
<class>WebsiteWidget</class>
|
226
|
+
<extends>QWebEngineView</extends>
|
227
|
+
<header>website_widget</header>
|
228
|
+
</customwidget>
|
229
|
+
<customwidget>
|
230
|
+
<class>BECQueue</class>
|
231
|
+
<extends>QTableWidget</extends>
|
232
|
+
<header>bec_queue</header>
|
233
|
+
</customwidget>
|
234
|
+
<customwidget>
|
235
|
+
<class>ScanControl</class>
|
236
|
+
<extends>QWidget</extends>
|
237
|
+
<header>scan_control</header>
|
238
|
+
</customwidget>
|
239
|
+
<customwidget>
|
240
|
+
<class>VSCodeEditor</class>
|
241
|
+
<extends>WebsiteWidget</extends>
|
242
|
+
<header>vs_code_editor</header>
|
243
|
+
</customwidget>
|
244
|
+
<customwidget>
|
245
|
+
<class>BECStatusBox</class>
|
246
|
+
<extends>QWidget</extends>
|
247
|
+
<header>bec_status_box</header>
|
248
|
+
</customwidget>
|
249
|
+
<customwidget>
|
250
|
+
<class>BECDockArea</class>
|
251
|
+
<extends>QWidget</extends>
|
252
|
+
<header>dock_area</header>
|
253
|
+
</customwidget>
|
254
|
+
<customwidget>
|
255
|
+
<class>QWebEngineView</class>
|
256
|
+
<extends></extends>
|
257
|
+
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
|
258
|
+
</customwidget>
|
259
|
+
</customwidgets>
|
260
|
+
<resources/>
|
261
|
+
<connections/>
|
262
|
+
</ui>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import webbrowser
|
2
|
+
|
3
|
+
|
4
|
+
class BECWebLinksMixin:
|
5
|
+
@staticmethod
|
6
|
+
def open_bec_docs():
|
7
|
+
webbrowser.open("https://beamline-experiment-control.readthedocs.io/en/latest/")
|
8
|
+
|
9
|
+
@staticmethod
|
10
|
+
def open_bec_widgets_docs():
|
11
|
+
webbrowser.open("https://bec.readthedocs.io/projects/bec-widgets/en/latest/")
|
12
|
+
|
13
|
+
@staticmethod
|
14
|
+
def open_bec_bug_report():
|
15
|
+
webbrowser.open("https://gitlab.psi.ch/groups/bec/-/issues/")
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# Copyright (C) 2022 The Qt Company Ltd.
|
2
2
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
3
3
|
|
4
|
-
from qtpy.QtCore import Slot
|
5
4
|
from qtpy.QtDesigner import QExtensionFactory, QPyDesignerTaskMenuExtension
|
6
5
|
from qtpy.QtGui import QAction
|
7
6
|
from qtpy.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout
|
8
7
|
from tictactoe import TicTacToe
|
9
8
|
|
9
|
+
from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
|
10
|
+
|
10
11
|
|
11
12
|
class TicTacToeDialog(QDialog): # pragma: no cover
|
12
13
|
def __init__(self, parent):
|
@@ -6,7 +6,7 @@ from qtpy.QtCore import QObject, Qt, Signal, Slot
|
|
6
6
|
from qtpy.QtWidgets import QApplication, QMessageBox, QPushButton, QVBoxLayout, QWidget
|
7
7
|
|
8
8
|
|
9
|
-
def SafeSlot(*slot_args, **slot_kwargs):
|
9
|
+
def SafeSlot(*slot_args, **slot_kwargs): # pylint: disable=invalid-name
|
10
10
|
"""Function with args, acting like a decorator, applying "error_managed" decorator + Qt Slot
|
11
11
|
to the passed function, to display errors instead of potentially raising an exception
|
12
12
|
|
@@ -34,10 +34,7 @@ class WarningPopupUtility(QObject):
|
|
34
34
|
Utility class to show warning popups in the application.
|
35
35
|
"""
|
36
36
|
|
37
|
-
|
38
|
-
super().__init__(parent)
|
39
|
-
|
40
|
-
@Slot(str, str, str, QWidget)
|
37
|
+
@SafeSlot(str, str, str, QWidget)
|
41
38
|
def show_warning_message(self, title, message, detailed_text, widget):
|
42
39
|
msg = QMessageBox(widget)
|
43
40
|
msg.setIcon(QMessageBox.Warning)
|
@@ -60,7 +57,10 @@ class WarningPopupUtility(QObject):
|
|
60
57
|
self.show_warning_message(title, message, detailed_text, widget)
|
61
58
|
|
62
59
|
|
63
|
-
|
60
|
+
_popup_utility_instance = None
|
61
|
+
|
62
|
+
|
63
|
+
class _ErrorPopupUtility(QObject):
|
64
64
|
"""
|
65
65
|
Utility class to manage error popups in the application to show error messages to the users.
|
66
66
|
This class is singleton and the error popup can be enabled or disabled globally or attach to widget methods with decorator @error_managed.
|
@@ -68,24 +68,14 @@ class ErrorPopupUtility(QObject):
|
|
68
68
|
|
69
69
|
error_occurred = Signal(str, str, QWidget)
|
70
70
|
|
71
|
-
_instance = None
|
72
|
-
_initialized = False
|
73
|
-
|
74
|
-
def __new__(cls, *args, **kwargs):
|
75
|
-
if cls._instance is None:
|
76
|
-
cls._instance = super(ErrorPopupUtility, cls).__new__(cls)
|
77
|
-
cls._instance._initialized = False
|
78
|
-
return cls._instance
|
79
|
-
|
80
71
|
def __init__(self, parent=None):
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
@Slot(str, str, QWidget)
|
72
|
+
super().__init__(parent=parent)
|
73
|
+
self.error_occurred.connect(self.show_error_message)
|
74
|
+
self.enable_error_popup = False
|
75
|
+
self._initialized = True
|
76
|
+
sys.excepthook = self.custom_exception_hook
|
77
|
+
|
78
|
+
@SafeSlot(str, str, QWidget)
|
89
79
|
def show_error_message(self, title, message, widget):
|
90
80
|
detailed_text = self.format_traceback(message)
|
91
81
|
error_message = self.parse_error_message(detailed_text)
|
@@ -157,13 +147,12 @@ class ErrorPopupUtility(QObject):
|
|
157
147
|
"""
|
158
148
|
self.enable_error_popup = bool(state)
|
159
149
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
cls._initialized = False
|
150
|
+
|
151
|
+
def ErrorPopupUtility():
|
152
|
+
global _popup_utility_instance
|
153
|
+
if not _popup_utility_instance:
|
154
|
+
_popup_utility_instance = _ErrorPopupUtility()
|
155
|
+
return _popup_utility_instance
|
167
156
|
|
168
157
|
|
169
158
|
class ExampleWidget(QWidget): # pragma: no cover
|
@@ -10,11 +10,11 @@ import yaml
|
|
10
10
|
from bec_lib.utils.import_utils import lazy_import_from
|
11
11
|
from pydantic import BaseModel, Field, field_validator
|
12
12
|
from qtpy.QtCore import QObject, QRunnable, QThreadPool, Signal
|
13
|
-
from qtpy.QtCore import Slot as pyqtSlot
|
14
13
|
from qtpy.QtWidgets import QApplication
|
15
14
|
|
16
15
|
from bec_widgets.cli.rpc_register import RPCRegister
|
17
16
|
from bec_widgets.qt_utils.error_popups import ErrorPopupUtility
|
17
|
+
from bec_widgets.qt_utils.error_popups import SafeSlot as pyqtSlot
|
18
18
|
from bec_widgets.utils.yaml_dialog import load_yaml, load_yaml_gui, save_yaml, save_yaml_gui
|
19
19
|
|
20
20
|
BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",))
|