qplotter 1.6.0b3__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.
- qplot/__init__.py +46 -0
- qplot/__main__.py +232 -0
- qplot/_auxiliary_paths.py +63 -0
- qplot/_metadata.py +12 -0
- qplot/_repair.py +14 -0
- qplot/_shutdown_supervisor.py +4049 -0
- qplot/_version.py +12 -0
- qplot/_windows_shutdown_job.py +1166 -0
- qplot/configuration/__init__.py +3 -0
- qplot/configuration/config.py +573 -0
- qplot/configuration/config_schema.json +319 -0
- qplot/configuration/scripts.py +255 -0
- qplot/configuration/themes/__init__.py +13 -0
- qplot/configuration/themes/_base.py +579 -0
- qplot/configuration/themes/blank.py +17 -0
- qplot/configuration/themes/dark.py +54 -0
- qplot/configuration/themes/light.py +54 -0
- qplot/datahandling/LoadFromDB.py +224 -0
- qplot/datahandling/__init__.py +47 -0
- qplot/datahandling/_trusted_live_helper.py +812 -0
- qplot/datahandling/_trusted_live_protocol.py +1745 -0
- qplot/datahandling/database.py +2330 -0
- qplot/datahandling/dimensions.py +43 -0
- qplot/datahandling/file_identity.py +461 -0
- qplot/datahandling/parameter_data.py +149 -0
- qplot/datahandling/plot_progress.py +17 -0
- qplot/datahandling/qcodes_cache.py +277 -0
- qplot/datahandling/qcodes_compat.py +14 -0
- qplot/datahandling/readSQL.py +2442 -0
- qplot/datahandling/readonly.py +2561 -0
- qplot/datahandling/source_activity.py +21 -0
- qplot/datahandling/trusted_array_preview.py +127 -0
- qplot/datahandling/trusted_derived_cache.py +1605 -0
- qplot/datahandling/trusted_derived_rendering.py +868 -0
- qplot/datahandling/trusted_heatmap.py +241 -0
- qplot/datahandling/trusted_live.py +2808 -0
- qplot/datahandling/trusted_live_queries.py +5907 -0
- qplot/datahandling/trusted_live_service.py +1894 -0
- qplot/datahandling/trusted_live_supervisor.py +2161 -0
- qplot/datahandling/trusted_plot.py +283 -0
- qplot/datahandling/trusted_presentation.py +1065 -0
- qplot/datahandling/trusted_snapshot.py +1132 -0
- qplot/datahandling/trusted_work_coordinator.py +2157 -0
- qplot/datahandling/trusted_work_scheduler.py +1204 -0
- qplot/diagnostics.py +241 -0
- qplot/resources/testdata/qplot_test_db_01_10mb.csv +11 -0
- qplot/resources/testdata/qplot_test_db_02_25mb.csv +14 -0
- qplot/resources/testdata/qplot_test_db_03_50mb.csv +17 -0
- qplot/resources/testdata/qplot_test_db_04_100mb.csv +20 -0
- qplot/resources/testdata/qplot_test_db_05_250mb.csv +23 -0
- qplot/resources/testdata/qplot_test_db_06_500mb.csv +26 -0
- qplot/resources/testdata/qplot_test_db_07_1gb.csv +29 -0
- qplot/resources/testdata/qplot_test_db_08_5gb.csv +32 -0
- qplot/resources/testdata/qplot_test_db_09_10gb.csv +35 -0
- qplot/resources/testdata/qplot_test_db_10_30gb.csv +38 -0
- qplot/testdata.py +1733 -0
- qplot/tools/__init__.py +13 -0
- qplot/tools/finite_means.py +114 -0
- qplot/tools/general.py +134 -0
- qplot/tools/heatmap_geometry.py +381 -0
- qplot/tools/operation_registry.py +179 -0
- qplot/tools/plot_tools.py +625 -0
- qplot/tools/sample_statistics.py +56 -0
- qplot/tools/worker.py +2787 -0
- qplot/windows/__init__.py +9 -0
- qplot/windows/_colorbar.py +422 -0
- qplot/windows/_commands.py +523 -0
- qplot/windows/_config_persistence.py +123 -0
- qplot/windows/_database_actions.py +4904 -0
- qplot/windows/_dataset_handle.py +221 -0
- qplot/windows/_dragdrop.py +71 -0
- qplot/windows/_export_paths.py +1167 -0
- qplot/windows/_help.py +169 -0
- qplot/windows/_native_averaging.py +173 -0
- qplot/windows/_native_transforms.py +389 -0
- qplot/windows/_plot1d_snap.py +608 -0
- qplot/windows/_plot1d_traces.py +2183 -0
- qplot/windows/_plot2d_colorbar.py +1126 -0
- qplot/windows/_plot2d_colorbar_dialog.py +786 -0
- qplot/windows/_plot2d_layers.py +2197 -0
- qplot/windows/_plot2d_sweeps.py +712 -0
- qplot/windows/_plotWin.py +1993 -0
- qplot/windows/_plot_actions.py +2695 -0
- qplot/windows/_plot_appearance.py +276 -0
- qplot/windows/_plot_axis_scaling.py +1485 -0
- qplot/windows/_plot_export.py +1445 -0
- qplot/windows/_plot_feedback.py +110 -0
- qplot/windows/_plot_marquee.py +656 -0
- qplot/windows/_plot_refresh.py +942 -0
- qplot/windows/_plot_state.py +239 -0
- qplot/windows/_plot_transform_labels.py +60 -0
- qplot/windows/_preferences.py +635 -0
- qplot/windows/_refresh_interval.py +70 -0
- qplot/windows/_run_controls.py +828 -0
- qplot/windows/_shortcuts.py +47 -0
- qplot/windows/_subplots/__init__.py +8 -0
- qplot/windows/_subplots/subplot1d.py +531 -0
- qplot/windows/_subplots/subplot2d.py +918 -0
- qplot/windows/_svg_export.py +209 -0
- qplot/windows/_trusted_derived_qt.py +1759 -0
- qplot/windows/_widgets/__init__.py +23 -0
- qplot/windows/_widgets/_run_formatting.py +387 -0
- qplot/windows/_widgets/details_tables.py +1119 -0
- qplot/windows/_widgets/dropbox.py +290 -0
- qplot/windows/_widgets/operations.py +460 -0
- qplot/windows/_widgets/preview.py +2997 -0
- qplot/windows/_widgets/run_list_items.py +488 -0
- qplot/windows/_widgets/toolbar.py +111 -0
- qplot/windows/_widgets/treeWidgets.py +2572 -0
- qplot/windows/_window_controls.py +413 -0
- qplot/windows/main.py +1635 -0
- qplot/windows/plot1d.py +311 -0
- qplot/windows/plot2d.py +1901 -0
- qplotter-1.6.0b3.dist-info/METADATA +318 -0
- qplotter-1.6.0b3.dist-info/RECORD +119 -0
- qplotter-1.6.0b3.dist-info/WHEEL +5 -0
- qplotter-1.6.0b3.dist-info/entry_points.txt +4 -0
- qplotter-1.6.0b3.dist-info/licenses/LICENSE +21 -0
- qplotter-1.6.0b3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
from collections import Counter
|
|
2
|
+
|
|
3
|
+
from PyQt6 import QtCore, QtGui
|
|
4
|
+
from PyQt6 import QtWidgets as qtw
|
|
5
|
+
|
|
6
|
+
from ._commands import create_action
|
|
7
|
+
from ._config_persistence import (
|
|
8
|
+
persist_config_value,
|
|
9
|
+
set_widget_value_without_signals,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
CONFIRM_CLOSE_ALL_KEY = "user_preference.confirm_close_all"
|
|
13
|
+
CONFIRM_QUIT_KEY = "user_preference.confirm_close"
|
|
14
|
+
DO_NOT_ASK_AGAIN_LABEL = "Don't ask again"
|
|
15
|
+
|
|
16
|
+
_WINDOW_LIST_ACTIONS_ATTRIBUTE = "_qplot_window_list_actions"
|
|
17
|
+
_WINDOW_LIST_ENTRY_PROPERTY = "qplotWindowListEntry"
|
|
18
|
+
_WINDOW_KIND_LABELS = {
|
|
19
|
+
"plot1d": "1D",
|
|
20
|
+
"plot2d": "2D",
|
|
21
|
+
"sweeper": "Cut",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _ApplicationQuitShortcutFilter(QtCore.QObject):
|
|
26
|
+
"""Deliver Quit while a modal dialog blocks its owner window."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, quit_action, parent):
|
|
29
|
+
super().__init__(parent)
|
|
30
|
+
self.quit_action = quit_action
|
|
31
|
+
|
|
32
|
+
def eventFilter(self, watched, event):
|
|
33
|
+
if (
|
|
34
|
+
event.type() != QtCore.QEvent.Type.KeyPress
|
|
35
|
+
or not isinstance(event, QtGui.QKeyEvent)
|
|
36
|
+
or event.isAutoRepeat()
|
|
37
|
+
):
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
key_sequence = QtGui.QKeySequence(event.keyCombination())
|
|
41
|
+
if any(
|
|
42
|
+
key_sequence.matches(shortcut)
|
|
43
|
+
== QtGui.QKeySequence.SequenceMatch.ExactMatch
|
|
44
|
+
for shortcut in self.quit_action.shortcuts()
|
|
45
|
+
):
|
|
46
|
+
self.quit_action.trigger()
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _install_application_quit_shortcut_filter(action_owner, quit_action):
|
|
53
|
+
"""Install the modal-dialog fallback for qPlot's Quit action."""
|
|
54
|
+
if getattr(action_owner, "_qplot_quit_shortcut_filter", None) is not None:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
app = qtw.QApplication.instance()
|
|
58
|
+
if app is None:
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
shortcut_filter = _ApplicationQuitShortcutFilter(quit_action, action_owner)
|
|
62
|
+
app.installEventFilter(shortcut_filter)
|
|
63
|
+
action_owner._qplot_quit_shortcut_filter = shortcut_filter
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def add_standard_window_controls(window):
|
|
67
|
+
"""
|
|
68
|
+
Adds standard window control actions to a QMainWindow menu bar.
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
window_menu = window.menuBar().addMenu("&Window")
|
|
72
|
+
|
|
73
|
+
main_front_back_action = create_action("window.main_front_back", window)
|
|
74
|
+
main_front_back_action.triggered.connect(lambda: toggle_main_window_front_back(window))
|
|
75
|
+
window_menu.addAction(main_front_back_action)
|
|
76
|
+
|
|
77
|
+
window_menu.addSeparator()
|
|
78
|
+
|
|
79
|
+
minimize_action = create_action("window.minimize", window)
|
|
80
|
+
minimize_action.triggered.connect(window.showMinimized)
|
|
81
|
+
window_menu.addAction(minimize_action)
|
|
82
|
+
|
|
83
|
+
maximize_action = create_action("window.maximize_restore", window)
|
|
84
|
+
maximize_action.triggered.connect(lambda: toggle_maximized(window))
|
|
85
|
+
window_menu.addAction(maximize_action)
|
|
86
|
+
|
|
87
|
+
fullscreen_action = create_action("window.full_screen", window)
|
|
88
|
+
fullscreen_action.triggered.connect(lambda: toggle_fullscreen(window))
|
|
89
|
+
window_menu.addAction(fullscreen_action)
|
|
90
|
+
|
|
91
|
+
# Plot windows are registered by the main window only after they have been
|
|
92
|
+
# constructed. Rebuild this section immediately before display so every
|
|
93
|
+
# Window menu reflects the currently open qPlot windows.
|
|
94
|
+
window_menu.aboutToShow.connect(
|
|
95
|
+
lambda: populate_available_window_actions(window, window_menu)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return window_menu
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def add_application_quit_action(window, menu, fallback_handler):
|
|
102
|
+
"""
|
|
103
|
+
Add qPlot's single application-wide Quit action to a File menu.
|
|
104
|
+
|
|
105
|
+
A shared action prevents Qt from treating identical application shortcuts
|
|
106
|
+
in the main and plot windows as ambiguous, while still exposing Quit in
|
|
107
|
+
every window's File menu.
|
|
108
|
+
"""
|
|
109
|
+
main_window = main_window_for(window)
|
|
110
|
+
action_owner = main_window if main_window is not None else window
|
|
111
|
+
quit_action = getattr(action_owner, "_qplot_quit_action", None)
|
|
112
|
+
|
|
113
|
+
if not isinstance(quit_action, QtGui.QAction):
|
|
114
|
+
quit_action = create_action("app.quit", action_owner)
|
|
115
|
+
quit_handler = getattr(action_owner, "quit_application", fallback_handler)
|
|
116
|
+
quit_action.triggered.connect(quit_handler)
|
|
117
|
+
action_owner._qplot_quit_action = quit_action
|
|
118
|
+
|
|
119
|
+
_install_application_quit_shortcut_filter(action_owner, quit_action)
|
|
120
|
+
menu.addAction(quit_action)
|
|
121
|
+
return quit_action
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def populate_available_window_actions(window, window_menu):
|
|
125
|
+
"""Add the current qPlot windows to the bottom of a Window menu."""
|
|
126
|
+
|
|
127
|
+
_remove_available_window_actions(window_menu)
|
|
128
|
+
|
|
129
|
+
main_window = main_window_for(window)
|
|
130
|
+
if main_window is None:
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
plot_windows = tuple(getattr(main_window, "windows", ()) or ())
|
|
134
|
+
labels = [_plot_window_menu_label(plot_window) for plot_window in plot_windows]
|
|
135
|
+
label_counts = Counter(labels)
|
|
136
|
+
label_indexes = Counter()
|
|
137
|
+
|
|
138
|
+
actions = [window_menu.addSeparator()]
|
|
139
|
+
actions.append(_add_window_menu_action(window_menu, main_window, "qPlot"))
|
|
140
|
+
for plot_window, label in zip(plot_windows, labels, strict=True):
|
|
141
|
+
label_indexes[label] += 1
|
|
142
|
+
if label_counts[label] > 1:
|
|
143
|
+
label = f"{label} ({label_indexes[label]})"
|
|
144
|
+
actions.append(_add_window_menu_action(window_menu, plot_window, label))
|
|
145
|
+
|
|
146
|
+
setattr(window_menu, _WINDOW_LIST_ACTIONS_ATTRIBUTE, actions)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _remove_available_window_actions(window_menu):
|
|
150
|
+
"""Remove actions generated during the previous Window-menu opening."""
|
|
151
|
+
|
|
152
|
+
for action in getattr(window_menu, _WINDOW_LIST_ACTIONS_ATTRIBUTE, ()):
|
|
153
|
+
window_menu.removeAction(action)
|
|
154
|
+
action.deleteLater()
|
|
155
|
+
setattr(window_menu, _WINDOW_LIST_ACTIONS_ATTRIBUTE, ())
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _plot_window_menu_label(plot_window):
|
|
159
|
+
"""Return a concise, recognisable label for a qPlot graph window."""
|
|
160
|
+
|
|
161
|
+
operation_kind = getattr(plot_window, "operation_kind", None)
|
|
162
|
+
kind_label = _WINDOW_KIND_LABELS.get(operation_kind)
|
|
163
|
+
label = str(getattr(plot_window, "label", "")).strip()
|
|
164
|
+
if not label:
|
|
165
|
+
window_title = getattr(plot_window, "windowTitle", None)
|
|
166
|
+
label = str(window_title()).strip() if callable(window_title) else "Plot"
|
|
167
|
+
|
|
168
|
+
return f"{kind_label} — {label}" if kind_label is not None else label
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _add_window_menu_action(menu, target_window, text):
|
|
172
|
+
"""Create a checked-as-active menu action that focuses ``target_window``."""
|
|
173
|
+
|
|
174
|
+
action = QtGui.QAction(text, menu)
|
|
175
|
+
action.setCheckable(True)
|
|
176
|
+
action.setChecked(target_window.isActiveWindow())
|
|
177
|
+
action.setProperty(_WINDOW_LIST_ENTRY_PROPERTY, True)
|
|
178
|
+
action.setStatusTip(f"Show {text}")
|
|
179
|
+
action.triggered.connect(
|
|
180
|
+
lambda _checked=False: focus_qplot_window(target_window)
|
|
181
|
+
)
|
|
182
|
+
menu.addAction(action)
|
|
183
|
+
return action
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def focus_qplot_window(target_window):
|
|
187
|
+
"""Restore, raise, and activate a qPlot window selected from the menu."""
|
|
188
|
+
|
|
189
|
+
if target_window.isMinimized():
|
|
190
|
+
target_window.showNormal()
|
|
191
|
+
elif not target_window.isVisible():
|
|
192
|
+
target_window.show()
|
|
193
|
+
|
|
194
|
+
target_window.raise_()
|
|
195
|
+
target_window.activateWindow()
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def add_confirmation_options(window, menu):
|
|
199
|
+
"""
|
|
200
|
+
Adds shared confirmation preferences to a menu.
|
|
201
|
+
|
|
202
|
+
"""
|
|
203
|
+
close_all_action = add_config_checkbox_action(
|
|
204
|
+
window,
|
|
205
|
+
menu,
|
|
206
|
+
"Confirm Before Closing All Plot Windows",
|
|
207
|
+
CONFIRM_CLOSE_ALL_KEY,
|
|
208
|
+
"Ask before closing every open plot window",
|
|
209
|
+
)
|
|
210
|
+
quit_action = add_config_checkbox_action(
|
|
211
|
+
window,
|
|
212
|
+
menu,
|
|
213
|
+
"Confirm Before Quit",
|
|
214
|
+
CONFIRM_QUIT_KEY,
|
|
215
|
+
"Ask before quitting qPlot",
|
|
216
|
+
)
|
|
217
|
+
return close_all_action, quit_action
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def add_restore_defaults_option(window, menu):
|
|
221
|
+
"""
|
|
222
|
+
Adds a reset-all-settings action to a menu.
|
|
223
|
+
|
|
224
|
+
"""
|
|
225
|
+
action = QtGui.QAction("Reset All Settings...", window)
|
|
226
|
+
action.setStatusTip("Reset all qPlot settings to their defaults")
|
|
227
|
+
action.triggered.connect(lambda: request_restore_defaults(window))
|
|
228
|
+
menu.addAction(action)
|
|
229
|
+
return action
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def request_restore_defaults(window):
|
|
233
|
+
"""
|
|
234
|
+
Requests a settings reset through the main window.
|
|
235
|
+
|
|
236
|
+
"""
|
|
237
|
+
if hasattr(window, "restore_default_settings"):
|
|
238
|
+
window.restore_default_settings()
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
main_window = main_window_for(window)
|
|
242
|
+
if main_window is not None and hasattr(main_window, "restore_default_settings"):
|
|
243
|
+
main_window.restore_default_settings()
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def add_config_checkbox_action(window, menu, text, key, status_tip):
|
|
247
|
+
"""
|
|
248
|
+
Adds a checkable config-backed action to a menu.
|
|
249
|
+
|
|
250
|
+
"""
|
|
251
|
+
action = QtGui.QAction(text, window)
|
|
252
|
+
action.setCheckable(True)
|
|
253
|
+
action.setStatusTip(status_tip)
|
|
254
|
+
|
|
255
|
+
def sync_checked():
|
|
256
|
+
action.blockSignals(True)
|
|
257
|
+
action.setChecked(window.config.get(key))
|
|
258
|
+
action.blockSignals(False)
|
|
259
|
+
|
|
260
|
+
sync_checked()
|
|
261
|
+
|
|
262
|
+
def persist_checked(checked):
|
|
263
|
+
previous_checked = window.config.get(key)
|
|
264
|
+
persist_config_value(
|
|
265
|
+
window,
|
|
266
|
+
window.config,
|
|
267
|
+
key,
|
|
268
|
+
checked,
|
|
269
|
+
"the confirmation preference",
|
|
270
|
+
lambda: set_widget_value_without_signals(
|
|
271
|
+
action,
|
|
272
|
+
action.setChecked,
|
|
273
|
+
previous_checked,
|
|
274
|
+
),
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
action.toggled.connect(persist_checked)
|
|
278
|
+
menu.aboutToShow.connect(sync_checked)
|
|
279
|
+
menu.addAction(action)
|
|
280
|
+
return action
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def close_all_warning_enabled(config):
|
|
284
|
+
"""
|
|
285
|
+
Returns whether closing all plot windows should ask first.
|
|
286
|
+
|
|
287
|
+
"""
|
|
288
|
+
return config.get(CONFIRM_CLOSE_ALL_KEY)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def ask_confirmation_with_dont_ask_again(
|
|
292
|
+
window,
|
|
293
|
+
title,
|
|
294
|
+
message,
|
|
295
|
+
config_key,
|
|
296
|
+
default_button=qtw.QMessageBox.StandardButton.No,
|
|
297
|
+
):
|
|
298
|
+
"""
|
|
299
|
+
Asks for confirmation and lets the user disable future prompts.
|
|
300
|
+
|
|
301
|
+
"""
|
|
302
|
+
parent = window if isinstance(window, qtw.QWidget) else None
|
|
303
|
+
box = qtw.QMessageBox(
|
|
304
|
+
qtw.QMessageBox.Icon.Question,
|
|
305
|
+
title,
|
|
306
|
+
message,
|
|
307
|
+
qtw.QMessageBox.StandardButton.Yes | qtw.QMessageBox.StandardButton.No,
|
|
308
|
+
parent,
|
|
309
|
+
)
|
|
310
|
+
box.setDefaultButton(default_button)
|
|
311
|
+
|
|
312
|
+
dont_ask_again = qtw.QCheckBox(DO_NOT_ASK_AGAIN_LABEL)
|
|
313
|
+
box.setCheckBox(dont_ask_again)
|
|
314
|
+
|
|
315
|
+
reply = box.exec()
|
|
316
|
+
if reply == qtw.QMessageBox.StandardButton.Yes and dont_ask_again.isChecked():
|
|
317
|
+
persist_config_value(
|
|
318
|
+
window,
|
|
319
|
+
window.config,
|
|
320
|
+
config_key,
|
|
321
|
+
False,
|
|
322
|
+
"the close-confirmation preference",
|
|
323
|
+
)
|
|
324
|
+
return reply
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def main_window_for(window):
|
|
328
|
+
"""
|
|
329
|
+
Finds the main qPlot window for shared window actions.
|
|
330
|
+
|
|
331
|
+
"""
|
|
332
|
+
app = qtw.QApplication.instance()
|
|
333
|
+
if app is None:
|
|
334
|
+
return window if window.__class__.__name__ == "MainWindow" else None
|
|
335
|
+
|
|
336
|
+
for top_level in qtw.QApplication.topLevelWidgets():
|
|
337
|
+
if top_level.__class__.__name__ == "MainWindow":
|
|
338
|
+
return top_level
|
|
339
|
+
|
|
340
|
+
return window if window.__class__.__name__ == "MainWindow" else None
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def toggle_main_window_front_back(window):
|
|
344
|
+
"""
|
|
345
|
+
Brings the main qPlot window forward, or behind qPlot graph windows.
|
|
346
|
+
|
|
347
|
+
"""
|
|
348
|
+
main_window = main_window_for(window)
|
|
349
|
+
if main_window is None:
|
|
350
|
+
return
|
|
351
|
+
|
|
352
|
+
if main_window.isActiveWindow():
|
|
353
|
+
send_main_window_behind_graphs(main_window, window)
|
|
354
|
+
return
|
|
355
|
+
|
|
356
|
+
if main_window.isMinimized():
|
|
357
|
+
main_window.showNormal()
|
|
358
|
+
else:
|
|
359
|
+
main_window.show()
|
|
360
|
+
|
|
361
|
+
main_window.raise_()
|
|
362
|
+
main_window.activateWindow()
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def send_main_window_behind_graphs(main_window, active_window):
|
|
366
|
+
"""
|
|
367
|
+
Places graph windows above the main qPlot window without lowering qPlot
|
|
368
|
+
behind unrelated applications.
|
|
369
|
+
|
|
370
|
+
"""
|
|
371
|
+
app = qtw.QApplication.instance()
|
|
372
|
+
if app is None:
|
|
373
|
+
return
|
|
374
|
+
|
|
375
|
+
graph_windows = [
|
|
376
|
+
window for window in qtw.QApplication.topLevelWidgets()
|
|
377
|
+
if window is not main_window
|
|
378
|
+
and window.isVisible()
|
|
379
|
+
and hasattr(window, "_guid")
|
|
380
|
+
and hasattr(window, "param")
|
|
381
|
+
]
|
|
382
|
+
if not graph_windows:
|
|
383
|
+
return
|
|
384
|
+
|
|
385
|
+
for graph_window in graph_windows:
|
|
386
|
+
graph_window.raise_()
|
|
387
|
+
|
|
388
|
+
if active_window in graph_windows:
|
|
389
|
+
active_window.activateWindow()
|
|
390
|
+
else:
|
|
391
|
+
graph_windows[-1].activateWindow()
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def toggle_maximized(window):
|
|
395
|
+
"""
|
|
396
|
+
Toggles a window between maximized and normal size.
|
|
397
|
+
|
|
398
|
+
"""
|
|
399
|
+
if window.isMaximized():
|
|
400
|
+
window.showNormal()
|
|
401
|
+
else:
|
|
402
|
+
window.showMaximized()
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def toggle_fullscreen(window):
|
|
406
|
+
"""
|
|
407
|
+
Toggles a window between full-screen and normal size.
|
|
408
|
+
|
|
409
|
+
"""
|
|
410
|
+
if window.isFullScreen():
|
|
411
|
+
window.showNormal()
|
|
412
|
+
else:
|
|
413
|
+
window.showFullScreen()
|