pymodaq 3.6.13__py3-none-any.whl → 4.0.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.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +13 -6
- pymodaq/control_modules/__init__.py +0 -7
- pymodaq/control_modules/daq_move.py +965 -2
- pymodaq/control_modules/daq_move_ui.py +319 -0
- pymodaq/control_modules/daq_viewer.py +1573 -3
- pymodaq/control_modules/daq_viewer_ui.py +393 -0
- pymodaq/control_modules/mocks.py +51 -0
- pymodaq/control_modules/move_utility_classes.py +709 -8
- pymodaq/control_modules/utils.py +256 -0
- pymodaq/control_modules/viewer_utility_classes.py +663 -6
- pymodaq/daq_utils.py +89 -0
- pymodaq/dashboard.py +91 -72
- pymodaq/examples/custom_app.py +12 -11
- pymodaq/examples/custom_viewer.py +10 -10
- pymodaq/examples/function_plotter.py +16 -13
- pymodaq/examples/nonlinearscanner.py +8 -6
- pymodaq/examples/parameter_ex.py +7 -7
- pymodaq/examples/preset_MockCamera.xml +1 -0
- pymodaq/extensions/__init__.py +16 -0
- pymodaq/extensions/console.py +76 -0
- pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
- pymodaq/extensions/daq_scan.py +1339 -0
- pymodaq/extensions/daq_scan_ui.py +240 -0
- pymodaq/extensions/h5browser.py +23 -0
- pymodaq/{pid → extensions/pid}/__init__.py +4 -2
- pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
- pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
- pymodaq/{pid → extensions/pid}/utils.py +52 -6
- pymodaq/extensions/utils.py +40 -0
- pymodaq/post_treatment/__init__.py +6 -0
- pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
- pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
- pymodaq/post_treatment/load_and_plot.py +219 -0
- pymodaq/post_treatment/process_to_scalar.py +263 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
- pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +32 -13
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
- pymodaq/utils/__init__.py +0 -29
- pymodaq/utils/abstract/__init__.py +48 -0
- pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
- pymodaq/utils/array_manipulation.py +379 -8
- pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
- pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
- pymodaq/utils/config.py +448 -0
- pymodaq/utils/conftests.py +5 -0
- pymodaq/utils/daq_utils.py +828 -8
- pymodaq/utils/data.py +1873 -7
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
- pymodaq/{daq_utils → utils}/enums.py +12 -7
- pymodaq/utils/exceptions.py +37 -0
- pymodaq/utils/factory.py +82 -0
- pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
- pymodaq/utils/gui_utils/custom_app.py +129 -0
- pymodaq/utils/gui_utils/file_io.py +66 -0
- pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
- pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
- pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
- pymodaq/utils/gui_utils/widgets/label.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
- pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
- pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
- pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
- pymodaq/utils/h5modules/__init__.py +1 -0
- pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
- pymodaq/utils/h5modules/browsing.py +683 -0
- pymodaq/utils/h5modules/data_saving.py +839 -0
- pymodaq/utils/h5modules/h5logging.py +110 -0
- pymodaq/utils/h5modules/module_saving.py +350 -0
- pymodaq/utils/h5modules/saving.py +914 -0
- pymodaq/utils/h5modules/utils.py +85 -0
- pymodaq/utils/logger.py +64 -6
- pymodaq/utils/managers/action_manager.py +460 -0
- pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
- pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
- pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
- pymodaq/utils/managers/parameter_manager.py +110 -0
- pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
- pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
- pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
- pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
- pymodaq/utils/math_utils.py +546 -10
- pymodaq/{daq_utils → utils}/messenger.py +5 -1
- pymodaq/utils/parameter/__init__.py +2 -15
- pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
- pymodaq/utils/parameter/utils.py +206 -11
- pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
- pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
- pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
- pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
- pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
- pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
- pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
- pymodaq/utils/plotting/navigator.py +355 -0
- pymodaq/utils/plotting/scan_selector.py +480 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
- pymodaq/utils/plotting/utils/filter.py +538 -0
- pymodaq/utils/plotting/utils/lineout.py +224 -0
- pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
- pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
- pymodaq/utils/plotting/widgets.py +76 -0
- pymodaq/utils/scanner/__init__.py +10 -0
- pymodaq/utils/scanner/scan_factory.py +204 -0
- pymodaq/utils/scanner/scanner.py +271 -0
- pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
- pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
- pymodaq/utils/scanner/scanners/sequential.py +192 -0
- pymodaq/utils/scanner/scanners/tabular.py +294 -0
- pymodaq/utils/scanner/utils.py +83 -0
- pymodaq/utils/slicing.py +47 -0
- pymodaq/utils/svg/__init__.py +6 -0
- pymodaq/utils/svg/svg_renderer.py +20 -0
- pymodaq/utils/svg/svg_view.py +35 -0
- pymodaq/utils/svg/svg_viewer2D.py +51 -0
- pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
- pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
- pymodaq/utils/units.py +216 -0
- pymodaq-4.0.1.dist-info/METADATA +159 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
- pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
- pymodaq/daq_move/daq_move_gui.py +0 -279
- pymodaq/daq_move/daq_move_gui.ui +0 -534
- pymodaq/daq_move/daq_move_main.py +0 -1042
- pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
- pymodaq/daq_move/utility_classes.py +0 -686
- pymodaq/daq_scan.py +0 -2160
- pymodaq/daq_utils/array_manipulation.py +0 -386
- pymodaq/daq_utils/config.py +0 -273
- pymodaq/daq_utils/conftests.py +0 -7
- pymodaq/daq_utils/custom_parameter_tree.py +0 -9
- pymodaq/daq_utils/daq_enums.py +0 -133
- pymodaq/daq_utils/daq_utils.py +0 -1402
- pymodaq/daq_utils/exceptions.py +0 -71
- pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
- pymodaq/daq_utils/gui_utils/file_io.py +0 -75
- pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
- pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
- pymodaq/daq_utils/h5exporters.py +0 -242
- pymodaq/daq_utils/h5modules.py +0 -1559
- pymodaq/daq_utils/h5utils.py +0 -241
- pymodaq/daq_utils/managers/action_manager.py +0 -236
- pymodaq/daq_utils/managers/parameter_manager.py +0 -57
- pymodaq/daq_utils/math_utils.py +0 -705
- pymodaq/daq_utils/parameter/__init__.py +0 -1
- pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
- pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
- pymodaq/daq_utils/parameter/utils.py +0 -136
- pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
- pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
- pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
- pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
- pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
- pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
- pymodaq/daq_utils/plotting/items/__init__.py +0 -0
- pymodaq/daq_utils/plotting/navigator.py +0 -500
- pymodaq/daq_utils/plotting/scan_selector.py +0 -289
- pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
- pymodaq/daq_utils/plotting/utils/filter.py +0 -236
- pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
- pymodaq/daq_utils/scanner.py +0 -1289
- pymodaq/daq_utils/tree_layout/__init__.py +0 -0
- pymodaq/daq_viewer/__init__.py +0 -0
- pymodaq/daq_viewer/daq_gui_settings.py +0 -237
- pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
- pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
- pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
- pymodaq/daq_viewer/utility_classes.py +0 -673
- pymodaq/examples/logger_image/__init__.py +0 -0
- pymodaq/examples/logger_image/logger_displayer.py +0 -121
- pymodaq/examples/logger_image/setup.svg +0 -3119
- pymodaq/examples/logger_image/setup_svg.py +0 -114
- pymodaq/h5browser.py +0 -39
- pymodaq/utils/scanner.py +0 -15
- pymodaq-3.6.13.dist-info/METADATA +0 -39
- pymodaq-3.6.13.dist-info/entry_points.txt +0 -8
- pymodaq-3.6.13.dist-info/top_level.txt +0 -1
- /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
- /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
- /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
- /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
- /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
- /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
- /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
- /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import datetime
|
|
3
|
+
from typing import List
|
|
3
4
|
|
|
4
|
-
from pymodaq.
|
|
5
|
+
from pymodaq.utils.logger import set_logger, get_module_name, get_module_name
|
|
6
|
+
from pymodaq.utils.config import Config
|
|
5
7
|
from qtpy import QtCore
|
|
6
8
|
from contextlib import contextmanager
|
|
7
9
|
from sqlalchemy import create_engine
|
|
8
10
|
from sqlalchemy.orm import sessionmaker
|
|
9
11
|
from sqlalchemy_utils import database_exists, create_database
|
|
10
|
-
from pymodaq.
|
|
11
|
-
|
|
12
|
-
from pymodaq.
|
|
13
|
-
from pymodaq.
|
|
14
|
-
from pymodaq.
|
|
12
|
+
from pymodaq.utils.db.db_logger.db_logger_models import Base, Data0D, Data1D, Data2D, LogInfo,\
|
|
13
|
+
Configuration, ControlModule
|
|
14
|
+
from pymodaq.utils import daq_utils as utils
|
|
15
|
+
from pymodaq.utils.gui_utils.utils import dashboard_submodules_params
|
|
16
|
+
from pymodaq.utils.messenger import messagebox, deprecation_msg
|
|
17
|
+
from pymodaq.utils.abstract.logger import AbstractLogger
|
|
15
18
|
from pyqtgraph.parametertree import Parameter, ParameterTree
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
logger =
|
|
21
|
+
logger = set_logger(get_module_name(__file__))
|
|
19
22
|
config = Config()
|
|
20
23
|
|
|
21
24
|
|
|
@@ -112,7 +115,7 @@ class DbLogger:
|
|
|
112
115
|
if self.engine is not None:
|
|
113
116
|
Base.metadata.create_all(self.engine)
|
|
114
117
|
|
|
115
|
-
def get_detectors(self, session):
|
|
118
|
+
def get_detectors(self, session) -> List[str]:
|
|
116
119
|
"""Returns the list of detectors name
|
|
117
120
|
|
|
118
121
|
Parameters
|
|
@@ -121,25 +124,51 @@ class DbLogger:
|
|
|
121
124
|
|
|
122
125
|
Returns
|
|
123
126
|
-------
|
|
124
|
-
list of
|
|
127
|
+
the list of all created detectors
|
|
125
128
|
"""
|
|
126
|
-
return [res[0] for res in session.query(
|
|
129
|
+
return [res[0] for res in session.query(ControlModule.name)]
|
|
130
|
+
|
|
131
|
+
def get_actuators(self, session) -> List[str]:
|
|
132
|
+
"""Returns the list of actuators name
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
session: (Session) SQLAlchemy session instance for db transactions
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
the list of all created actuators
|
|
141
|
+
"""
|
|
142
|
+
return [res[0] for res in session.query(ControlModule.name)]
|
|
127
143
|
|
|
128
144
|
def add_detectors(self, detectors):
|
|
129
145
|
"""
|
|
130
146
|
add detectors in the detectors table
|
|
131
147
|
Parameters
|
|
132
148
|
----------
|
|
133
|
-
session: (Session) SQLAlchemy session instance for db transactions
|
|
134
149
|
detectors: (list) list of dict with keys: name and settings_xml
|
|
135
150
|
"""
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
self.add_control_modules(detectors, 'DAQ_Viewer')
|
|
152
|
+
|
|
153
|
+
def add_actuators(self, actuators):
|
|
154
|
+
"""
|
|
155
|
+
add actuators in the actuators table
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
actuators: list
|
|
159
|
+
list of dict with keys: name and settings_xml
|
|
160
|
+
"""
|
|
161
|
+
self.add_control_modules(actuators, 'DAQ_Move')
|
|
162
|
+
|
|
163
|
+
def add_control_modules(self, modules, module_type='DAQ_Viewer'):
|
|
164
|
+
if not isinstance(modules, list):
|
|
165
|
+
modules = [modules]
|
|
138
166
|
with self.session_scope() as session:
|
|
139
|
-
|
|
140
|
-
for
|
|
141
|
-
if
|
|
142
|
-
session.add(
|
|
167
|
+
existing_modules = [d.name for d in session.query(ControlModule)]
|
|
168
|
+
for mod in modules:
|
|
169
|
+
if mod['name'] not in existing_modules:
|
|
170
|
+
session.add(ControlModule(name=mod['name'], module_type=module_type,
|
|
171
|
+
settings_xml=mod['xml_settings']))
|
|
143
172
|
|
|
144
173
|
def add_config(self, config_settings):
|
|
145
174
|
with self.session_scope() as session:
|
|
@@ -149,37 +178,44 @@ class DbLogger:
|
|
|
149
178
|
with self.session_scope() as session:
|
|
150
179
|
session.add(LogInfo(log))
|
|
151
180
|
|
|
152
|
-
def
|
|
181
|
+
def add_data(self, data):
|
|
153
182
|
with self.session_scope() as session:
|
|
154
|
-
time_stamp =
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
self.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if 'data0D' in
|
|
163
|
-
for channel in
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
time_stamp = data['acq_time_s']
|
|
184
|
+
module_name = data['name']
|
|
185
|
+
|
|
186
|
+
if session.query(ControlModule).filter_by(name=module_name).count() == 0:
|
|
187
|
+
self.add_control_modules(session, dict(name=module_name), data['control_module'])
|
|
188
|
+
|
|
189
|
+
module_id = session.query(ControlModule).filter_by(name=module_name).one().id # detector/actuator names should/are unique
|
|
190
|
+
|
|
191
|
+
if 'data0D' in data:
|
|
192
|
+
for channel in data['data0D']:
|
|
193
|
+
d = data['data0D'][channel]['data']
|
|
194
|
+
if hasattr(d, '__len__'):
|
|
195
|
+
d = float(d[0])
|
|
196
|
+
if data['control_module'] == 'DAQ_Move':
|
|
197
|
+
channel = f"{data['data0D'][channel]['name']}"
|
|
198
|
+
else:
|
|
199
|
+
channel = f"{data['data0D'][channel]['name']}:{channel}"
|
|
200
|
+
session.add(Data0D(timestamp=time_stamp, control_module_id=module_id, channel=channel, value=d))
|
|
201
|
+
|
|
202
|
+
if 'data1D' in data:
|
|
203
|
+
for channel in data['data1D']:
|
|
204
|
+
session.add(Data1D(timestamp=time_stamp, control_module_id=module_id,
|
|
205
|
+
channel=f"{data['data1D'][channel]['name']}:{channel}",
|
|
206
|
+
value=data['data1D'][channel]['data'].tolist()))
|
|
207
|
+
|
|
208
|
+
if 'data2D' in data and self.save2D:
|
|
209
|
+
for channel in data['data2D']:
|
|
210
|
+
session.add(Data2D(timestamp=time_stamp, control_module_id=module_id,
|
|
211
|
+
channel=f"{data['data2D'][channel]['name']}:{channel}",
|
|
212
|
+
value=data['data2D'][channel]['data'].tolist()))
|
|
179
213
|
|
|
180
214
|
# not yet dataND as db should not know where to save these datas
|
|
181
215
|
|
|
182
216
|
|
|
217
|
+
|
|
218
|
+
|
|
183
219
|
class DbLoggerGUI(DbLogger, QtCore.QObject):
|
|
184
220
|
params = [
|
|
185
221
|
{'title': 'Database:', 'name': 'database_type', 'type': 'list', 'value': 'PostgreSQL',
|
|
@@ -276,10 +312,13 @@ class DataBaseLogger(AbstractLogger):
|
|
|
276
312
|
def add_detector(self, det_name, settings):
|
|
277
313
|
self.dblogger.add_detectors([dict(name=det_name, xml_settings=settings)])
|
|
278
314
|
|
|
279
|
-
def
|
|
280
|
-
self.dblogger.
|
|
281
|
-
|
|
282
|
-
|
|
315
|
+
def add_actuator(self, act_name, settings):
|
|
316
|
+
self.dblogger.add_actuators([dict(name=act_name, xml_settings=settings)])
|
|
317
|
+
|
|
318
|
+
def add_data(self, data):
|
|
319
|
+
self.dblogger.add_data(data)
|
|
320
|
+
self.settings.child('N_saved').setValue(
|
|
321
|
+
self.settings.child('N_saved').value() + 1)
|
|
283
322
|
|
|
284
323
|
def stop_logger(self):
|
|
285
324
|
pass
|
|
@@ -15,18 +15,39 @@ class Configuration(Base):
|
|
|
15
15
|
def __repr__(self):
|
|
16
16
|
return f"<Config(date='{datetime.datetime.fromtimestamp(self.timestamp).isoformat()}', settings_xml='{self.settings_xml[0:20]}')>"
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
# class Actuator(Base):
|
|
19
|
+
# __tablename__ = 'actuators'
|
|
20
|
+
# id = Column(Integer, primary_key=True)
|
|
21
|
+
# name = Column(String(128))
|
|
22
|
+
# settings_xml = Column(String)
|
|
23
|
+
# datas0D = relationship("Data0D", backref='actuators')
|
|
24
|
+
#
|
|
25
|
+
#
|
|
26
|
+
# class Detector(Base):
|
|
27
|
+
# __tablename__ = 'detectors'
|
|
28
|
+
# id = Column(Integer, primary_key=True)
|
|
29
|
+
# name = Column(String(128))
|
|
30
|
+
# settings_xml = Column(String)
|
|
31
|
+
# datas0D = relationship("Data0D", backref='detectors')
|
|
32
|
+
# datas1D = relationship("Data1D", backref='detectors')
|
|
33
|
+
# datas2D = relationship("Data2D", backref='detectors')
|
|
34
|
+
#
|
|
35
|
+
# def __repr__(self):
|
|
36
|
+
# return f"<Detector(name='{self.name}', settings_xml='{self.settings_xml[0:20]}')>"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ControlModule(Base):
|
|
40
|
+
__tablename__ = 'control_modules'
|
|
21
41
|
id = Column(Integer, primary_key=True)
|
|
22
42
|
name = Column(String(128))
|
|
43
|
+
module_type = Column(String(128))
|
|
23
44
|
settings_xml = Column(String)
|
|
24
|
-
datas0D = relationship("Data0D", backref='
|
|
25
|
-
datas1D = relationship("Data1D", backref='
|
|
26
|
-
datas2D = relationship("Data2D", backref='
|
|
45
|
+
datas0D = relationship("Data0D", backref='control_modules')
|
|
46
|
+
datas1D = relationship("Data1D", backref='control_modules')
|
|
47
|
+
datas2D = relationship("Data2D", backref='control_modules')
|
|
27
48
|
|
|
28
49
|
def __repr__(self):
|
|
29
|
-
return f"<
|
|
50
|
+
return f"<Control Module {self.type} (name='{self.name}', settings_xml='{self.settings_xml[0:20]}')>"
|
|
30
51
|
|
|
31
52
|
|
|
32
53
|
class LogInfo(Base):
|
|
@@ -43,7 +64,7 @@ class Data0D(Base):
|
|
|
43
64
|
|
|
44
65
|
id = Column(Integer, primary_key=True)
|
|
45
66
|
timestamp = Column(Integer, nullable=False, index=True)
|
|
46
|
-
|
|
67
|
+
control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
|
|
47
68
|
channel = Column(String(128))
|
|
48
69
|
value = Column(Float)
|
|
49
70
|
|
|
@@ -56,7 +77,7 @@ class Data1D(Base):
|
|
|
56
77
|
|
|
57
78
|
id = Column(Integer, primary_key=True)
|
|
58
79
|
timestamp = Column(Integer, nullable=False, index=True)
|
|
59
|
-
|
|
80
|
+
control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
|
|
60
81
|
channel = Column(String(128))
|
|
61
82
|
value = Column(Array(Float, dimensions=1))
|
|
62
83
|
|
|
@@ -69,7 +90,7 @@ class Data2D(Base):
|
|
|
69
90
|
|
|
70
91
|
id = Column(Integer, primary_key=True)
|
|
71
92
|
timestamp = Column(Integer, nullable=False, index=True)
|
|
72
|
-
|
|
93
|
+
control_module_id = Column(Integer, ForeignKey('control_modules.id'), index=True)
|
|
73
94
|
channel = Column(String(128))
|
|
74
95
|
value = Column(Array(Float, dimensions=2))
|
|
75
96
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created the 11/01/2023
|
|
4
|
-
|
|
5
|
-
@author: Sebastien Weber
|
|
6
|
-
"""
|
|
7
1
|
from enum import Enum
|
|
2
|
+
from pymodaq.utils.daq_utils import find_index
|
|
3
|
+
from pymodaq.utils.math_utils import my_moment
|
|
4
|
+
import numpy as np
|
|
5
|
+
from scipy.optimize import curve_fit
|
|
8
6
|
from typing import List, Union
|
|
9
7
|
|
|
10
8
|
|
|
@@ -31,11 +29,15 @@ class BaseEnum(Enum):
|
|
|
31
29
|
|
|
32
30
|
def enum_checker(enum: BaseEnum, item: Union[BaseEnum, str]):
|
|
33
31
|
"""Check if the item parameter is a valid enum or at least one valid string name of the enum
|
|
32
|
+
|
|
34
33
|
If a string, transforms it to a valid enum (case not important)
|
|
34
|
+
|
|
35
35
|
Parameters
|
|
36
36
|
----------
|
|
37
37
|
enum: BaseEnum class or one of its derivated class
|
|
38
|
+
|
|
38
39
|
item: str or BaseEnum instance
|
|
40
|
+
|
|
39
41
|
Returns
|
|
40
42
|
-------
|
|
41
43
|
BaseEnum class or one of its derivated class
|
|
@@ -52,4 +54,7 @@ def enum_checker(enum: BaseEnum, item: Union[BaseEnum, str]):
|
|
|
52
54
|
else:
|
|
53
55
|
raise ValueError(f'{item} is an invalid {enum}. Should be a {enum} enum or '
|
|
54
56
|
f'a string in {enum.names()}')
|
|
55
|
-
return item
|
|
57
|
+
return item
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class DAQ_ScanException(Exception):
|
|
2
|
+
"""Raised when an error occur within the DAQScan"""
|
|
3
|
+
pass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DetectorError(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ActuatorError(Exception):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ViewerError(Exception):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ExpectedError(Exception):
|
|
22
|
+
"""Raised in the tests made for pymodaq plugins"""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Expected_1(ExpectedError):
|
|
27
|
+
"""Expected error 1 for pymodaq tests"""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Expected_2(ExpectedError):
|
|
32
|
+
"""Expected error 2 for pymodaq tests"""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Expected_3(ExpectedError):
|
|
37
|
+
"""Expected error 3 for pymodaq tests"""
|
pymodaq/utils/factory.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created the 04/11/2022
|
|
4
|
+
|
|
5
|
+
@author: Sebastien Weber
|
|
6
|
+
"""
|
|
7
|
+
from typing import Callable, Union
|
|
8
|
+
from abc import ABCMeta, abstractmethod
|
|
9
|
+
|
|
10
|
+
from pymodaq.utils.logger import set_logger, get_module_name
|
|
11
|
+
|
|
12
|
+
logger = set_logger(get_module_name(__file__))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BuilderBase(ABCMeta):
|
|
16
|
+
"""Abstract class defining an object/service builder with a callable interface accepting some arguments
|
|
17
|
+
|
|
18
|
+
See https://realpython.com/factory-method-python/ for some details
|
|
19
|
+
|
|
20
|
+
See Also
|
|
21
|
+
--------
|
|
22
|
+
pymodaq.post_treatment.process_1d_to_scalar
|
|
23
|
+
"""
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def __call__(self, *args, **kwargs):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ObjectFactory(metaclass=ABCMeta):
|
|
30
|
+
"""Generic ObjectFactory with a decorator register to add object builders to the factory with a unique key
|
|
31
|
+
identifier
|
|
32
|
+
|
|
33
|
+
See https://realpython.com/factory-method-python/ for some details
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
@ObjectFactory.register('custom')
|
|
38
|
+
def my_custom_builder():
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
See Also
|
|
42
|
+
--------
|
|
43
|
+
pymodaq.post_treatment.process_1d_to_scalar.Data1DProcessorFactory
|
|
44
|
+
"""
|
|
45
|
+
_builders = {}
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def register(cls, key: str) -> Callable:
|
|
49
|
+
def inner_wrapper(wrapped_class: Union[BuilderBase, Callable]) -> Callable:
|
|
50
|
+
if cls.__name__ not in cls._builders:
|
|
51
|
+
cls._builders[cls.__name__] = {}
|
|
52
|
+
if key not in cls._builders[cls.__name__]:
|
|
53
|
+
cls._builders[cls.__name__][key] = wrapped_class
|
|
54
|
+
else:
|
|
55
|
+
logger.warning(f'The {cls.__name__}/{key} builder is already registered. Replacing it')
|
|
56
|
+
return wrapped_class
|
|
57
|
+
return inner_wrapper
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def builders(self):
|
|
61
|
+
return self._builders
|
|
62
|
+
|
|
63
|
+
def keys_function(self, do_sort=True):
|
|
64
|
+
if do_sort:
|
|
65
|
+
return self.keys
|
|
66
|
+
else:
|
|
67
|
+
return list(self.builders[self.__class__.__name__].keys())
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def keys(self):
|
|
71
|
+
return sorted(list(self.builders[self.__class__.__name__].keys()))
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def create(cls, key, **kwargs):
|
|
75
|
+
builder = cls._builders[cls.__name__].get(key)
|
|
76
|
+
if not builder:
|
|
77
|
+
raise ValueError(key)
|
|
78
|
+
return builder(**kwargs)
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def get_class(cls, key):
|
|
82
|
+
return cls._builders[cls.__name__].get(key)
|
|
@@ -3,8 +3,8 @@ from .list_picker import ListPicker
|
|
|
3
3
|
from .custom_app import CustomApp
|
|
4
4
|
from .file_io import select_file
|
|
5
5
|
from .widgets.table import TableView, TableModel, SpinBoxDelegate, BooleanDelegate
|
|
6
|
-
from .widgets.lcd import LCD
|
|
7
6
|
from .widgets.push import PushButtonIcon, EditPush, EditPushRel, EditPushInfo
|
|
8
7
|
from .widgets.qled import QLED
|
|
9
8
|
from .widgets.spinbox import QSpinBox_ro
|
|
10
9
|
|
|
10
|
+
from .utils import get_splash_sc
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from qtpy.QtCore import QObject, QLocale
|
|
2
|
+
from pymodaq.utils.gui_utils.dock import DockArea
|
|
3
|
+
from pymodaq.utils.managers.action_manager import ActionManager
|
|
4
|
+
from pymodaq.utils.managers.parameter_manager import ParameterManager
|
|
5
|
+
from pyqtgraph.dockarea import DockArea
|
|
6
|
+
from qtpy import QtCore, QtWidgets
|
|
7
|
+
from typing import Union
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CustomApp(QObject, ActionManager, ParameterManager):
|
|
11
|
+
"""Base Class to ease the implementation of User Interfaces
|
|
12
|
+
|
|
13
|
+
Inherits the MixIns ActionManager and ParameterManager classes. You have to subclass some methods and make
|
|
14
|
+
concrete implementation of a given number of methods:
|
|
15
|
+
|
|
16
|
+
* setup_actions: mandatory, see :class:`pymodaq.utils.managers.action_manager.ActionManager`
|
|
17
|
+
* value_changed: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
|
|
18
|
+
* child_added: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
|
|
19
|
+
* param_deleted: non mandatory, see :class:`pymodaq.utils.managers.parameter_manager.ParameterManager`
|
|
20
|
+
* setup_docks: mandatory
|
|
21
|
+
* setup_menu: non mandatory
|
|
22
|
+
* connect_things: mandatory
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
parent: DockArea or QtWidget
|
|
27
|
+
dashboard: DashBoard, optional
|
|
28
|
+
|
|
29
|
+
See Also
|
|
30
|
+
--------
|
|
31
|
+
:class:`pymodaq.utils.managers.action_manager.ActionManager`,
|
|
32
|
+
:class:`pymodaq.utils.managers.parameter_manager.ParameterManager`,
|
|
33
|
+
:class:`pymodaq.utils.managers.modules_manager.ModulesManager`,
|
|
34
|
+
:class:`pymodaq.dashboard.DashBoard`
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
log_signal = QtCore.Signal(str)
|
|
38
|
+
params = []
|
|
39
|
+
|
|
40
|
+
def __init__(self, parent: Union[DockArea, QtWidgets.QWidget], dashboard=None):
|
|
41
|
+
QObject.__init__(self)
|
|
42
|
+
ActionManager.__init__(self)
|
|
43
|
+
ParameterManager.__init__(self)
|
|
44
|
+
QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
|
|
45
|
+
|
|
46
|
+
if not isinstance(parent, DockArea):
|
|
47
|
+
if not isinstance(parent, QtWidgets.QWidget):
|
|
48
|
+
raise Exception('no valid parent container, expected a DockArea or a least a QWidget')
|
|
49
|
+
|
|
50
|
+
self.parent = parent
|
|
51
|
+
if isinstance(parent, DockArea):
|
|
52
|
+
self.dockarea: DockArea = parent
|
|
53
|
+
self.mainwindow: QtWidgets.QMainWindow = parent.parent()
|
|
54
|
+
else:
|
|
55
|
+
self.dockarea: DockArea = None
|
|
56
|
+
self.mainwindow: QtWidgets.QMainWindow = None
|
|
57
|
+
self.dashboard = dashboard
|
|
58
|
+
|
|
59
|
+
self.docks = dict([])
|
|
60
|
+
self.statusbar = None
|
|
61
|
+
self._toolbar = QtWidgets.QToolBar()
|
|
62
|
+
|
|
63
|
+
if self.mainwindow is not None:
|
|
64
|
+
self.mainwindow.addToolBar(self._toolbar)
|
|
65
|
+
self.statusbar = self.mainwindow.statusBar()
|
|
66
|
+
|
|
67
|
+
self.set_toolbar(self._toolbar)
|
|
68
|
+
|
|
69
|
+
def setup_ui(self):
|
|
70
|
+
self.setup_docks()
|
|
71
|
+
|
|
72
|
+
self.setup_actions() # see ActionManager MixIn class
|
|
73
|
+
|
|
74
|
+
self.setup_menu()
|
|
75
|
+
|
|
76
|
+
self.connect_things()
|
|
77
|
+
|
|
78
|
+
def setup_docks(self):
|
|
79
|
+
"""Mandatory method to be subclassed to setup the docks layout
|
|
80
|
+
|
|
81
|
+
Examples
|
|
82
|
+
--------
|
|
83
|
+
>>>self.docks['ADock'] = gutils.Dock('ADock name')
|
|
84
|
+
>>>self.dockarea.addDock(self.docks['ADock'])
|
|
85
|
+
>>>self.docks['AnotherDock'] = gutils.Dock('AnotherDock name')
|
|
86
|
+
>>>self.dockarea.addDock(self.docks['AnotherDock'''], 'bottom', self.docks['ADock'])
|
|
87
|
+
|
|
88
|
+
See Also
|
|
89
|
+
--------
|
|
90
|
+
pyqtgraph.dockarea.Dock
|
|
91
|
+
"""
|
|
92
|
+
raise NotImplementedError
|
|
93
|
+
|
|
94
|
+
def setup_menu(self):
|
|
95
|
+
"""Non mandatory method to be subclassed in order to create a menubar
|
|
96
|
+
|
|
97
|
+
create menu for actions contained into the self._actions, for instance:
|
|
98
|
+
|
|
99
|
+
Examples
|
|
100
|
+
--------
|
|
101
|
+
>>>file_menu = self._menubar.addMenu('File')
|
|
102
|
+
>>>self.affect_to('load', file_menu)
|
|
103
|
+
>>>self.affect_to('save', file_menu)
|
|
104
|
+
|
|
105
|
+
>>>file_menu.addSeparator()
|
|
106
|
+
>>>self.affect_to('quit', file_menu)
|
|
107
|
+
|
|
108
|
+
See Also
|
|
109
|
+
--------
|
|
110
|
+
pymodaq.utils.managers.action_manager.ActionManager
|
|
111
|
+
"""
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
def connect_things(self):
|
|
115
|
+
"""Connect actions and/or other widgets signal to methods"""
|
|
116
|
+
raise NotImplementedError
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def modules_manager(self):
|
|
120
|
+
"""useful tool to interact with DAQ_Moves and DAQ_Viewers
|
|
121
|
+
|
|
122
|
+
Will be available if a DashBoard has been set
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
ModulesManager
|
|
127
|
+
"""
|
|
128
|
+
if self.dashboard is not None:
|
|
129
|
+
return self.dashboard.modules_manager
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from pymodaq.utils.config import Config
|
|
4
|
+
from qtpy import QtWidgets
|
|
5
|
+
|
|
6
|
+
config = Config()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def select_file(start_path=config('data_saving', 'h5file', 'save_path'), save=True, ext=None, filter=None,
|
|
10
|
+
force_save_extension=False):
|
|
11
|
+
"""Opens a selection file popup for loading or saving a file
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
start_path: str or Path
|
|
16
|
+
The strating point in the file/folder system to open the popup from
|
|
17
|
+
save: bool
|
|
18
|
+
if True, ask you to enter a filename (with or without extension)
|
|
19
|
+
ext: str
|
|
20
|
+
the extension string, e.g. xml, h5, png ...
|
|
21
|
+
filter: list of string
|
|
22
|
+
list of possible extensions, mostly valid for loading
|
|
23
|
+
force_save_extension: bool
|
|
24
|
+
if True force the extension of the saved file to be set to ext
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
Path: the Path object of the file to save or load
|
|
29
|
+
"""
|
|
30
|
+
if ext is None:
|
|
31
|
+
ext = '.h5'
|
|
32
|
+
|
|
33
|
+
if filter is None:
|
|
34
|
+
if not save:
|
|
35
|
+
if not isinstance(ext, list):
|
|
36
|
+
ext = [ext]
|
|
37
|
+
filter = "Data files ("
|
|
38
|
+
for ext_tmp in ext:
|
|
39
|
+
filter += '*.' + ext_tmp + " "
|
|
40
|
+
filter += ")"
|
|
41
|
+
|
|
42
|
+
if start_path is not None:
|
|
43
|
+
if not isinstance(start_path, str):
|
|
44
|
+
start_path = str(start_path)
|
|
45
|
+
if save:
|
|
46
|
+
fname = QtWidgets.QFileDialog.getSaveFileName(None, 'Enter a file name', start_path,
|
|
47
|
+
filter)
|
|
48
|
+
else:
|
|
49
|
+
fname = QtWidgets.QFileDialog.getOpenFileName(None, 'Select a file name', start_path, filter)
|
|
50
|
+
|
|
51
|
+
fname = fname[0]
|
|
52
|
+
if fname != '': # execute if the user didn't cancel the file selection
|
|
53
|
+
fname = Path(fname)
|
|
54
|
+
if save and force_save_extension:
|
|
55
|
+
parent = fname.parent
|
|
56
|
+
filename = fname.stem
|
|
57
|
+
fname = parent.joinpath(filename + "." + ext) # forcing the right extension on the filename
|
|
58
|
+
return fname # fname is a Path object
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if __name__ == '__main__':
|
|
62
|
+
import sys
|
|
63
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
64
|
+
file = select_file(save=True, filter="Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)")
|
|
65
|
+
print(file)
|
|
66
|
+
sys.exit(app.exec_())
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pickle
|
|
2
2
|
|
|
3
|
-
from pymodaq.
|
|
4
|
-
from pymodaq.
|
|
3
|
+
from pymodaq.utils import config as config_mod
|
|
4
|
+
from pymodaq.utils.gui_utils.file_io import select_file
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def load_layout_state(dockarea, file=None):
|