pymodaq 3.6.12__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.12.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
- {pymodaq-3.6.12.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 -671
- 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.12.dist-info/METADATA +0 -39
- pymodaq-3.6.12.dist-info/entry_points.txt +0 -8
- pymodaq-3.6.12.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.12.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,1626 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created on Mon Dec 4 10:59:53 2017
|
|
4
|
-
|
|
5
|
-
@author: Weber
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
import sys
|
|
9
|
-
from qtpy import QtWidgets, QtGui
|
|
10
|
-
from qtpy.QtCore import Slot, Signal, Qt, QDate, QDateTime, QTime, QByteArray, QSize
|
|
11
|
-
from pyqtgraph.widgets import ColorButton, SpinBox
|
|
12
|
-
import pyqtgraph.parametertree.parameterTypes as pTypes
|
|
13
|
-
from pyqtgraph.parametertree import Parameter, ParameterItem
|
|
14
|
-
from pyqtgraph.parametertree.Parameter import registerParameterType
|
|
15
|
-
from pyqtgraph import functions as fn
|
|
16
|
-
from pyqtgraph.colormap import ColorMap
|
|
17
|
-
from pymodaq.daq_utils.daq_utils import scroll_log, scroll_linear
|
|
18
|
-
from collections import OrderedDict
|
|
19
|
-
from decimal import Decimal as D
|
|
20
|
-
|
|
21
|
-
from pymodaq.daq_utils.gui_utils.widgets import QLED
|
|
22
|
-
|
|
23
|
-
from pathlib import Path
|
|
24
|
-
import numpy as np
|
|
25
|
-
import os
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class GroupParameterItemCustom(pTypes.GroupParameterItem):
|
|
29
|
-
"""
|
|
30
|
-
| Group parameters are used mainly as a generic parent item that holds (and groups!) a set of child parameters. It also provides a simple mechanism for displaying a button or combo that can be used to add new parameters to the group.
|
|
31
|
-
|
|
|
32
|
-
| This customization is made in order to respond to the visible options.
|
|
33
|
-
| Overwrite the optsChanged method from GroupParameterItem class.
|
|
34
|
-
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
def __init__(self, param, depth):
|
|
38
|
-
pTypes.GroupParameterItem.__init__(self, param, depth)
|
|
39
|
-
|
|
40
|
-
def optsChanged(self, param, changed):
|
|
41
|
-
if 'addList' in changed:
|
|
42
|
-
self.updateAddList()
|
|
43
|
-
elif 'visible' in changed:
|
|
44
|
-
self.setHidden(not changed['visible'])
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class GroupParameterCustom(pTypes.GroupParameter):
|
|
48
|
-
"""
|
|
49
|
-
|
|
|
50
|
-
| Group parameters are used mainly as a generic parent item that holds (and groups!) a set of child parameters.
|
|
51
|
-
|
|
|
52
|
-
| It also provides a simple mechanism for displaying a button or combo that can be used to add new parameters to the group.
|
|
53
|
-
|
|
|
54
|
-
| To enable this, the group must be initialized with the 'addText' option (the text will be displayed on a button which, when clicked, will cause addNew() to be called).
|
|
55
|
-
|
|
|
56
|
-
| If the 'addList' option is specified as well, then a dropdown-list of addable items will be displayed instead of a button.
|
|
57
|
-
|
|
|
58
|
-
|
|
59
|
-
============== ========================================
|
|
60
|
-
**Attributes** **Type**
|
|
61
|
-
itemClass instance of GroupParameterItemCustom
|
|
62
|
-
============== ========================================
|
|
63
|
-
"""
|
|
64
|
-
itemClass = GroupParameterItemCustom
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
registerParameterType('group', GroupParameterCustom, override=True)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class SpinBoxCustom(SpinBox.SpinBox):
|
|
71
|
-
def __init__(self, parent=None, value=0.0, **kwargs):
|
|
72
|
-
super().__init__(parent, value, **kwargs)
|
|
73
|
-
|
|
74
|
-
def setOpts(self, **opts):
|
|
75
|
-
"""
|
|
76
|
-
Overriden class to add the field visible in the options.
|
|
77
|
-
|
|
78
|
-
=============== =========== ======================
|
|
79
|
-
**Parameters** **Type** **Description**
|
|
80
|
-
*opts* string the vararg options
|
|
81
|
-
=============== =========== ======================
|
|
82
|
-
"""
|
|
83
|
-
# print opts
|
|
84
|
-
for k in opts:
|
|
85
|
-
if k == 'bounds' or k == 'limits':
|
|
86
|
-
self.setMinimum(opts[k][0], update=False)
|
|
87
|
-
self.setMaximum(opts[k][1], update=False)
|
|
88
|
-
elif k == 'min':
|
|
89
|
-
self.setMinimum(opts[k], update=False)
|
|
90
|
-
elif k == 'max':
|
|
91
|
-
self.setMaximum(opts[k], update=False)
|
|
92
|
-
elif k in ['step', 'minStep']:
|
|
93
|
-
self.opts[k] = D(str(opts[k]))
|
|
94
|
-
elif k == 'value':
|
|
95
|
-
pass # # don't set value until bounds have been set
|
|
96
|
-
elif k == 'visible':
|
|
97
|
-
self.setVisible(opts[k])
|
|
98
|
-
elif k == 'readonly':
|
|
99
|
-
self.setReadOnly(opts[k])
|
|
100
|
-
elif k == 'enabled':
|
|
101
|
-
self.setEnabled(opts[k])
|
|
102
|
-
elif k == 'format':
|
|
103
|
-
self.opts[k] = opts[k]
|
|
104
|
-
elif k in self.opts:
|
|
105
|
-
self.opts[k] = opts[k]
|
|
106
|
-
elif 'tip' in k:
|
|
107
|
-
self.opts[k] = opts[k]
|
|
108
|
-
self.setToolTip(opts[k])
|
|
109
|
-
if 'value' in opts:
|
|
110
|
-
self.setValue(opts['value'])
|
|
111
|
-
|
|
112
|
-
# # If bounds have changed, update value to match
|
|
113
|
-
if 'bounds' in opts and 'value' not in opts:
|
|
114
|
-
self.setValue()
|
|
115
|
-
|
|
116
|
-
# # sanity checks:
|
|
117
|
-
if self.opts['int']:
|
|
118
|
-
if 'step' in opts:
|
|
119
|
-
step = opts['step']
|
|
120
|
-
# # not necessary..
|
|
121
|
-
# if int(step) != step:
|
|
122
|
-
# raise Exception('Integer SpinBox must have integer step size.')
|
|
123
|
-
else:
|
|
124
|
-
self.opts['step'] = int(self.opts['step'])
|
|
125
|
-
|
|
126
|
-
if 'minStep' in opts:
|
|
127
|
-
step = opts['minStep']
|
|
128
|
-
if int(step) != step:
|
|
129
|
-
raise Exception('Integer SpinBox must have integer minStep size.')
|
|
130
|
-
else:
|
|
131
|
-
ms = int(self.opts.get('minStep', 1))
|
|
132
|
-
if ms < 1:
|
|
133
|
-
ms = 1
|
|
134
|
-
self.opts['minStep'] = ms
|
|
135
|
-
|
|
136
|
-
if 'delay' in opts:
|
|
137
|
-
self.proxy.setDelay(opts['delay'])
|
|
138
|
-
|
|
139
|
-
self.updateText()
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
class Pixmap_check(QtWidgets.QWidget):
|
|
143
|
-
""" value of this parameter is a dict with checked, data for the pixmap and optionally path in h5 node
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
# valuechanged=Signal(dict)
|
|
147
|
-
|
|
148
|
-
def __init__(self):
|
|
149
|
-
|
|
150
|
-
super().__init__()
|
|
151
|
-
self.path = ''
|
|
152
|
-
self.data = None
|
|
153
|
-
self.checked = False
|
|
154
|
-
self.initUI()
|
|
155
|
-
|
|
156
|
-
def initUI(self):
|
|
157
|
-
"""
|
|
158
|
-
Init the User Interface.
|
|
159
|
-
"""
|
|
160
|
-
self.ver_layout = QtWidgets.QVBoxLayout()
|
|
161
|
-
self.label = QtWidgets.QLabel()
|
|
162
|
-
self.checkbox = QtWidgets.QCheckBox('Show/Hide')
|
|
163
|
-
self.info = QtWidgets.QLineEdit()
|
|
164
|
-
self.info.setReadOnly(True)
|
|
165
|
-
self.checkbox.setChecked(False)
|
|
166
|
-
self.ver_layout.addWidget(self.label)
|
|
167
|
-
self.ver_layout.addWidget(self.info)
|
|
168
|
-
self.ver_layout.addWidget(self.checkbox)
|
|
169
|
-
self.ver_layout.setSpacing(0)
|
|
170
|
-
self.ver_layout.setContentsMargins(0, 0, 0, 0)
|
|
171
|
-
self.setLayout(self.ver_layout)
|
|
172
|
-
|
|
173
|
-
def setValue(self, dic):
|
|
174
|
-
if 'data' in dic:
|
|
175
|
-
if not isinstance(dic['data'], QtGui.QPixmap):
|
|
176
|
-
self.data = QByteArray(dic['data'])
|
|
177
|
-
im = QtGui.QImage.fromData(self.data)
|
|
178
|
-
a = QtGui.QPixmap.fromImage(im)
|
|
179
|
-
else:
|
|
180
|
-
a = dic['data']
|
|
181
|
-
else:
|
|
182
|
-
a = dic['pixmap']
|
|
183
|
-
if 'path' in dic:
|
|
184
|
-
self.path = dic['path']
|
|
185
|
-
else:
|
|
186
|
-
self.path = ''
|
|
187
|
-
if 'info' in dic:
|
|
188
|
-
info = dic['info']
|
|
189
|
-
else:
|
|
190
|
-
info = ''
|
|
191
|
-
self.label.setPixmap(a)
|
|
192
|
-
self.checkbox.setChecked(dic['checked'])
|
|
193
|
-
self.info.setText(info)
|
|
194
|
-
# self.valuechanged.emit(dic)
|
|
195
|
-
|
|
196
|
-
def value(self):
|
|
197
|
-
return dict(pixmap=self.label.pixmap(), checked=self.checkbox.isChecked(), path=self.path)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class QTimeCustom(QtWidgets.QTimeEdit):
|
|
201
|
-
def __init__(self, *args, **kwargs):
|
|
202
|
-
super(QTimeCustom, self).__init__(*args, **kwargs)
|
|
203
|
-
self.minutes_increment = 1
|
|
204
|
-
self.timeChanged.connect(self.updateTime)
|
|
205
|
-
|
|
206
|
-
def setTime(self, time):
|
|
207
|
-
hours = time.hour()
|
|
208
|
-
minutes = time.minute()
|
|
209
|
-
|
|
210
|
-
minutes = int(np.round(minutes / self.minutes_increment) * self.minutes_increment)
|
|
211
|
-
if minutes == 60:
|
|
212
|
-
minutes = 0
|
|
213
|
-
hours += 1
|
|
214
|
-
|
|
215
|
-
time.setHMS(hours, minutes, 0)
|
|
216
|
-
|
|
217
|
-
return super(QTimeCustom, self).setTime(time)
|
|
218
|
-
|
|
219
|
-
def setMinuteIncrement(self, minutes_increment):
|
|
220
|
-
self.minutes_increment = minutes_increment
|
|
221
|
-
self.updateTime(self.time())
|
|
222
|
-
|
|
223
|
-
@Slot(QTime)
|
|
224
|
-
def updateTime(self, time):
|
|
225
|
-
self.setTime(time)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
class SliderSpinBox(QtWidgets.QWidget):
|
|
229
|
-
|
|
230
|
-
def __init__(self, *args, subtype='lin', **kwargs):
|
|
231
|
-
|
|
232
|
-
super().__init__()
|
|
233
|
-
self.subtype = subtype
|
|
234
|
-
self.initUI(*args, **kwargs)
|
|
235
|
-
|
|
236
|
-
self.valueChanged = self.spinbox.valueChanged # (value) for compatibility with QSpinBox
|
|
237
|
-
self.sigValueChanged = self.spinbox.sigValueChanged # (self)
|
|
238
|
-
self.sigValueChanging = self.spinbox.sigValueChanging # (self, value) sent immediately; no delay.
|
|
239
|
-
|
|
240
|
-
@property
|
|
241
|
-
def opts(self):
|
|
242
|
-
return self.spinbox.opts
|
|
243
|
-
|
|
244
|
-
@opts.setter
|
|
245
|
-
def opts(self, **opts):
|
|
246
|
-
self.setOpts(**opts)
|
|
247
|
-
|
|
248
|
-
def setOpts(self, **opts):
|
|
249
|
-
self.spinbox.setOpts(**opts)
|
|
250
|
-
if 'visible' in opts:
|
|
251
|
-
self.slider.setVisible(opts['visible'])
|
|
252
|
-
|
|
253
|
-
def insert_widget(self,widget, row=0):
|
|
254
|
-
self.vlayout.insertWidget(row, widget)
|
|
255
|
-
|
|
256
|
-
def initUI(self, *args, **kwargs):
|
|
257
|
-
"""
|
|
258
|
-
Init the User Interface.
|
|
259
|
-
"""
|
|
260
|
-
self.vlayout = QtWidgets.QVBoxLayout()
|
|
261
|
-
self.slider = QtWidgets.QSlider(Qt.Horizontal)
|
|
262
|
-
self.slider.setMinimumWidth(50)
|
|
263
|
-
self.slider.setMinimum(0)
|
|
264
|
-
self.slider.setMaximum(100)
|
|
265
|
-
if 'value' in kwargs:
|
|
266
|
-
value = kwargs.pop('value')
|
|
267
|
-
else:
|
|
268
|
-
if 'bounds' in kwargs:
|
|
269
|
-
value = kwargs['bounds'][0]
|
|
270
|
-
else:
|
|
271
|
-
value = 1
|
|
272
|
-
self.spinbox = SpinBoxCustom(parent=None, value=value, **kwargs)
|
|
273
|
-
|
|
274
|
-
self.vlayout.addWidget(self.slider)
|
|
275
|
-
self.vlayout.addWidget(self.spinbox)
|
|
276
|
-
self.vlayout.setSpacing(0)
|
|
277
|
-
self.vlayout.setContentsMargins(0, 0, 0, 0)
|
|
278
|
-
self.setLayout(self.vlayout)
|
|
279
|
-
|
|
280
|
-
self.slider.valueChanged.connect(self.update_spinbox)
|
|
281
|
-
self.spinbox.valueChanged.connect(self.update_slide)
|
|
282
|
-
|
|
283
|
-
def update_spinbox(self, val):
|
|
284
|
-
"""
|
|
285
|
-
val is a percentage [0-100] used in order to set the spinbox value between its min and max
|
|
286
|
-
"""
|
|
287
|
-
min_val = float(self.opts['bounds'][0])
|
|
288
|
-
max_val = float(self.opts['bounds'][1])
|
|
289
|
-
if self.subtype == 'log':
|
|
290
|
-
val_out = scroll_log(val, min_val, max_val)
|
|
291
|
-
else:
|
|
292
|
-
val_out = scroll_linear(val, min_val, max_val)
|
|
293
|
-
try:
|
|
294
|
-
self.slider.valueChanged.disconnect(self.update_spinbox)
|
|
295
|
-
self.spinbox.valueChanged.disconnect(self.update_slide)
|
|
296
|
-
except Exception:
|
|
297
|
-
pass
|
|
298
|
-
self.spinbox.setValue(val_out)
|
|
299
|
-
|
|
300
|
-
self.slider.valueChanged.connect(self.update_spinbox)
|
|
301
|
-
self.spinbox.valueChanged.connect(self.update_slide)
|
|
302
|
-
|
|
303
|
-
def update_slide(self, val):
|
|
304
|
-
"""
|
|
305
|
-
val is the spinbox value between its min and max
|
|
306
|
-
"""
|
|
307
|
-
min_val = float(self.opts['bounds'][0])
|
|
308
|
-
max_val = float(self.opts['bounds'][1])
|
|
309
|
-
|
|
310
|
-
try:
|
|
311
|
-
self.slider.valueChanged.disconnect(self.update_spinbox)
|
|
312
|
-
self.spinbox.valueChanged.disconnect(self.update_slide)
|
|
313
|
-
except Exception:
|
|
314
|
-
pass
|
|
315
|
-
self.slider.setValue(int((val - min_val) / (max_val - min_val) * 100))
|
|
316
|
-
self.slider.valueChanged.connect(self.update_spinbox)
|
|
317
|
-
self.spinbox.valueChanged.connect(self.update_slide)
|
|
318
|
-
|
|
319
|
-
def setValue(self, val):
|
|
320
|
-
self.spinbox.setValue(val)
|
|
321
|
-
|
|
322
|
-
def value(self):
|
|
323
|
-
return self.spinbox.value()
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
class WidgetParameterItem(pTypes.WidgetParameterItem):
|
|
327
|
-
"""
|
|
328
|
-
This is a subclass of widget parameteritem in order to deal with the visiblily of the spinbox when parameter visibility os toggled.
|
|
329
|
-
"""
|
|
330
|
-
|
|
331
|
-
def __init__(self, param, depth):
|
|
332
|
-
pTypes.WidgetParameterItem.__init__(self, param, depth)
|
|
333
|
-
if 'enabled' in self.param.opts:
|
|
334
|
-
self.displayLabel.setEnabled(self.param.opts['enabled'])
|
|
335
|
-
|
|
336
|
-
def makeWidget(self):
|
|
337
|
-
"""
|
|
338
|
-
| Return a single widget that should be placed in the second tree column.
|
|
339
|
-
| The widget must be given three attributes:
|
|
340
|
-
|
|
341
|
-
========== ============================================================
|
|
342
|
-
sigChanged a signal that is emitted when the widget's value is changed
|
|
343
|
-
value a function that returns the value
|
|
344
|
-
setValue a function that sets the value
|
|
345
|
-
========== ============================================================
|
|
346
|
-
|
|
347
|
-
| This is a good function to override in subclasses.
|
|
348
|
-
|
|
349
|
-
"""
|
|
350
|
-
opts = self.param.opts
|
|
351
|
-
t = opts['type']
|
|
352
|
-
if t in ('int', 'float', 'slide'):
|
|
353
|
-
defs = {
|
|
354
|
-
'value': 0, 'min': None, 'max': None,
|
|
355
|
-
'step': 1.0, 'dec': False,
|
|
356
|
-
'siPrefix': False, 'suffix': '', 'decimals': 12,
|
|
357
|
-
}
|
|
358
|
-
if t == 'int':
|
|
359
|
-
defs['int'] = True
|
|
360
|
-
defs['minStep'] = 1.0
|
|
361
|
-
for k in defs:
|
|
362
|
-
if k in opts:
|
|
363
|
-
defs[k] = opts[k]
|
|
364
|
-
if 'limits' in opts:
|
|
365
|
-
defs['bounds'] = opts['limits']
|
|
366
|
-
if t in ('int', 'float'):
|
|
367
|
-
w = SpinBoxCustom()
|
|
368
|
-
else:
|
|
369
|
-
if 'subtype' not in opts:
|
|
370
|
-
opts['subtype'] = 'linear'
|
|
371
|
-
if 'limits' not in opts:
|
|
372
|
-
defs['bounds'] = (0., self.param.value()) #max value set to default value when no max given
|
|
373
|
-
else:
|
|
374
|
-
defs['bounds'] = opts['limits']
|
|
375
|
-
|
|
376
|
-
w = SliderSpinBox(subtype=opts['subtype'], bounds=defs['bounds'], value=defs['value'])
|
|
377
|
-
self.setSizeHint(1, QSize(50, 50))
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
w.setOpts(**defs)
|
|
381
|
-
w.sigChanged = w.sigValueChanged
|
|
382
|
-
w.sigChanging = w.sigValueChanging
|
|
383
|
-
|
|
384
|
-
elif t == 'bool':
|
|
385
|
-
w = QtWidgets.QCheckBox()
|
|
386
|
-
w.sigChanged = w.toggled
|
|
387
|
-
w.value = w.isChecked
|
|
388
|
-
w.setValue = w.setChecked
|
|
389
|
-
w.setEnabled(not opts.get('readonly', False))
|
|
390
|
-
self.hideWidget = False
|
|
391
|
-
elif t == 'bool_push':
|
|
392
|
-
w = QtWidgets.QPushButton()
|
|
393
|
-
if 'label' in opts:
|
|
394
|
-
w.setText(opts['label'])
|
|
395
|
-
elif 'title' in opts:
|
|
396
|
-
w.setText(opts['title'])
|
|
397
|
-
else:
|
|
398
|
-
w.setText(opts['name'])
|
|
399
|
-
# w.setMaximumWidth(50)
|
|
400
|
-
w.setCheckable(True)
|
|
401
|
-
w.sigChanged = w.toggled
|
|
402
|
-
w.value = w.isChecked
|
|
403
|
-
w.setValue = w.setChecked
|
|
404
|
-
w.setEnabled(not opts.get('readonly', False))
|
|
405
|
-
self.hideWidget = False
|
|
406
|
-
elif t == 'led_push':
|
|
407
|
-
w = QLED()
|
|
408
|
-
w.clickable = True
|
|
409
|
-
w.set_as_false()
|
|
410
|
-
w.sigChanged = w.value_changed
|
|
411
|
-
w.value = w.get_state
|
|
412
|
-
w.setValue = w.set_as
|
|
413
|
-
self.hideWidget = False
|
|
414
|
-
elif t == 'str':
|
|
415
|
-
w = QtWidgets.QLineEdit()
|
|
416
|
-
w.sigChanged = w.editingFinished
|
|
417
|
-
w.value = lambda: str(w.text())
|
|
418
|
-
w.setValue = lambda v: w.setText(str(v))
|
|
419
|
-
w.sigChanging = w.textChanged
|
|
420
|
-
elif t == 'color':
|
|
421
|
-
w = ColorButton.ColorButton()
|
|
422
|
-
w.sigChanged = w.sigColorChanged
|
|
423
|
-
w.sigChanging = w.sigColorChanging
|
|
424
|
-
w.value = w.color
|
|
425
|
-
w.setValue = w.setColor
|
|
426
|
-
self.hideWidget = False
|
|
427
|
-
w.setFlat(True)
|
|
428
|
-
w.setEnabled(not opts.get('readonly', False))
|
|
429
|
-
elif t == 'colormap':
|
|
430
|
-
from pyqtgraph.widgets.GradientWidget import GradientWidget # # need this here to avoid import loop
|
|
431
|
-
w = GradientWidget(orientation='bottom')
|
|
432
|
-
w.sigChanged = w.sigGradientChangeFinished
|
|
433
|
-
w.sigChanging = w.sigGradientChanged
|
|
434
|
-
w.value = w.colorMap
|
|
435
|
-
w.setValue = w.setColorMap
|
|
436
|
-
self.hideWidget = False
|
|
437
|
-
elif t == 'date_time':
|
|
438
|
-
w = QtWidgets.QDateTimeEdit(QDateTime(QDate.currentDate(), QTime.currentTime()))
|
|
439
|
-
w.setCalendarPopup(True)
|
|
440
|
-
if 'format' in opts:
|
|
441
|
-
w.setDisplayFormat(opts['format'])
|
|
442
|
-
else:
|
|
443
|
-
w.setDisplayFormat('dd/MM/yyyy hh:mm')
|
|
444
|
-
w.sigChanged = w.dateTimeChanged
|
|
445
|
-
w.value = w.dateTime
|
|
446
|
-
w.setValue = w.setDateTime
|
|
447
|
-
elif t == 'date':
|
|
448
|
-
w = QtWidgets.QDateEdit(QDate(QDate.currentDate()))
|
|
449
|
-
w.setCalendarPopup(True)
|
|
450
|
-
if 'format' in opts:
|
|
451
|
-
w.setDisplayFormat(opts['format'])
|
|
452
|
-
else:
|
|
453
|
-
w.setDisplayFormat('dd/MM/yyyy')
|
|
454
|
-
w.sigChanged = w.dateChanged
|
|
455
|
-
w.value = w.date
|
|
456
|
-
w.setValue = w.setDate
|
|
457
|
-
|
|
458
|
-
elif t == 'time':
|
|
459
|
-
w = QTimeCustom(QTime(QTime.currentTime()))
|
|
460
|
-
if 'minutes_increment' in opts:
|
|
461
|
-
w.setMinuteIncrement(opts['minutes_increment'])
|
|
462
|
-
w.setDisplayFormat('hh:mm')
|
|
463
|
-
w.sigChanged = w.timeChanged
|
|
464
|
-
w.value = w.time
|
|
465
|
-
w.setValue = w.setTime
|
|
466
|
-
|
|
467
|
-
elif t == 'led':
|
|
468
|
-
w = QLED()
|
|
469
|
-
w.clickable = False
|
|
470
|
-
w.set_as_false()
|
|
471
|
-
w.sigChanged = w.value_changed
|
|
472
|
-
w.value = w.get_state
|
|
473
|
-
w.setValue = w.set_as
|
|
474
|
-
elif t == 'pixmap':
|
|
475
|
-
w = QtWidgets.QLabel()
|
|
476
|
-
w.sigChanged = None
|
|
477
|
-
w.value = w.pixmap
|
|
478
|
-
w.setValue = w.setPixmap
|
|
479
|
-
elif t == 'pixmap_check':
|
|
480
|
-
w = Pixmap_check()
|
|
481
|
-
w.sigChanged = w.checkbox.toggled
|
|
482
|
-
w.value = w.value
|
|
483
|
-
w.setValue = w.setValue
|
|
484
|
-
else:
|
|
485
|
-
raise Exception("Unknown type '%s'" % str(t))
|
|
486
|
-
return w
|
|
487
|
-
|
|
488
|
-
def limitsChanged(self, param, limits):
|
|
489
|
-
"""Called when the parameter's limits have changed"""
|
|
490
|
-
ParameterItem.limitsChanged(self, param, limits)
|
|
491
|
-
|
|
492
|
-
t = self.param.opts['type']
|
|
493
|
-
if t == 'int' or t == 'float' or t == 'slide':
|
|
494
|
-
self.widget.setOpts(bounds=limits)
|
|
495
|
-
else:
|
|
496
|
-
return # don't know what to do with any other types..
|
|
497
|
-
|
|
498
|
-
def showEditor(self):
|
|
499
|
-
"""
|
|
500
|
-
Show the widget attribute.
|
|
501
|
-
"""
|
|
502
|
-
self.widget.show()
|
|
503
|
-
self.displayLabel.hide()
|
|
504
|
-
self.widget.setFocus(Qt.OtherFocusReason)
|
|
505
|
-
if isinstance(self.widget, SpinBox.SpinBox):
|
|
506
|
-
self.widget.selectNumber() # select the numerical portion of the text for quick editing
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
def hideEditor(self):
|
|
510
|
-
"""
|
|
511
|
-
Hide the widget attribute.
|
|
512
|
-
"""
|
|
513
|
-
status = 'led' in self.param.opts['type'] or self.param.opts['type'] == 'pixmap'
|
|
514
|
-
status = not (status or self.param.opts['type'] == 'pixmap_check')
|
|
515
|
-
if status:
|
|
516
|
-
self.widget.hide()
|
|
517
|
-
self.displayLabel.show()
|
|
518
|
-
|
|
519
|
-
def optsChanged(self, param, opts):
|
|
520
|
-
"""
|
|
521
|
-
| Called when any options are changed that are not name, value, default, or limits.
|
|
522
|
-
|
|
|
523
|
-
| If widget is a SpinBox, pass options straight through.
|
|
524
|
-
| So that only the display label is shown when visible option is toggled.
|
|
525
|
-
|
|
526
|
-
=============== ================================== ==============================
|
|
527
|
-
**Parameters** **Type** **Description**
|
|
528
|
-
*param* instance of pyqtgraph parameter the parameter to check
|
|
529
|
-
*opts* string list the associated options list
|
|
530
|
-
=============== ================================== ==============================
|
|
531
|
-
|
|
532
|
-
See Also
|
|
533
|
-
--------
|
|
534
|
-
optsChanged
|
|
535
|
-
"""
|
|
536
|
-
# print "opts changed:", opts
|
|
537
|
-
ParameterItem.optsChanged(self, param, opts)
|
|
538
|
-
|
|
539
|
-
if 'readonly' in opts:
|
|
540
|
-
self.updateDefaultBtn()
|
|
541
|
-
if isinstance(self.widget, (QtWidgets.QCheckBox, ColorButton.ColorButton)):
|
|
542
|
-
self.widget.setEnabled(not opts['readonly'])
|
|
543
|
-
|
|
544
|
-
if 'minutes_increment' in opts:
|
|
545
|
-
self.widget.setMinuteIncrement(opts['minutes_increment'])
|
|
546
|
-
|
|
547
|
-
if 'tip' in opts:
|
|
548
|
-
self.displayLabel.setToolTip(opts['tip'])
|
|
549
|
-
|
|
550
|
-
# # If widget is a SpinBox, pass options straight through
|
|
551
|
-
if isinstance(self.widget, SpinBoxCustom) or isinstance(self.widget, SliderSpinBox):
|
|
552
|
-
if 'visible' in opts:
|
|
553
|
-
opts.pop('visible')
|
|
554
|
-
self.widget.hide() # so that only the display label is shown when visible option is toggled
|
|
555
|
-
if 'units' in opts and 'suffix' not in opts:
|
|
556
|
-
opts['suffix'] = opts['units']
|
|
557
|
-
self.widget.setOpts(**opts)
|
|
558
|
-
self.updateDisplayLabel()
|
|
559
|
-
|
|
560
|
-
if 'title' in opts:
|
|
561
|
-
self.setText(0, opts['title']) # void QTreeWidgetItem::setText(int column, const QString &text)
|
|
562
|
-
|
|
563
|
-
def valueChanged(self, param, val, force=False):
|
|
564
|
-
# # called when the parameter's value has changed
|
|
565
|
-
ParameterItem.valueChanged(self, param, val)
|
|
566
|
-
if self.widget.sigChanged is not None:
|
|
567
|
-
self.widget.sigChanged.disconnect(self.widgetValueChanged)
|
|
568
|
-
|
|
569
|
-
try:
|
|
570
|
-
if force or val != self.widget.value():
|
|
571
|
-
self.widget.setValue(val)
|
|
572
|
-
self.updateDisplayLabel(val) # # always make sure label is updated, even if values match!
|
|
573
|
-
finally:
|
|
574
|
-
if self.widget.sigChanged is not None:
|
|
575
|
-
self.widget.sigChanged.connect(self.widgetValueChanged)
|
|
576
|
-
self.updateDefaultBtn()
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
class SimpleParameterCustom(pTypes.SimpleParameter):
|
|
580
|
-
itemClass = WidgetParameterItem
|
|
581
|
-
|
|
582
|
-
def __init__(self, *args, **kargs):
|
|
583
|
-
pTypes.SimpleParameter.__init__(self, *args, **kargs)
|
|
584
|
-
|
|
585
|
-
def _interpretValue(self, v):
|
|
586
|
-
fn = {
|
|
587
|
-
'int': int,
|
|
588
|
-
'float': float,
|
|
589
|
-
'bool': bool,
|
|
590
|
-
'bool_push': bool,
|
|
591
|
-
'str': str,
|
|
592
|
-
'color': self._interpColor,
|
|
593
|
-
'colormap': self._interpColormap,
|
|
594
|
-
'date_time': QDateTime,
|
|
595
|
-
'date': QDate,
|
|
596
|
-
'time': QTime,
|
|
597
|
-
'led': bool,
|
|
598
|
-
'led_push': bool,
|
|
599
|
-
'pixmap': QtWidgets.QLabel,
|
|
600
|
-
'pixmap_check': dict,
|
|
601
|
-
'slide': float
|
|
602
|
-
}[self.opts['type']]
|
|
603
|
-
return fn(v)
|
|
604
|
-
|
|
605
|
-
def _interpColor(self, v):
|
|
606
|
-
return fn.mkColor(v)
|
|
607
|
-
|
|
608
|
-
def _interpColormap(self, v):
|
|
609
|
-
if not isinstance(v, ColorMap):
|
|
610
|
-
raise TypeError("Cannot set colormap parameter from object %r" % v)
|
|
611
|
-
return v
|
|
612
|
-
|
|
613
|
-
def setLimits(self, limits):
|
|
614
|
-
"""Set limits on the acceptable values for this parameter.
|
|
615
|
-
The format of limits depends on the type of the parameter and
|
|
616
|
-
some parameters do not make use of limits at all."""
|
|
617
|
-
if 'limits' in self.opts and self.opts['limits'] == limits:
|
|
618
|
-
return
|
|
619
|
-
self.opts['limits'] = limits
|
|
620
|
-
self.sigLimitsChanged.emit(self, limits)
|
|
621
|
-
if self.opts['type'] in ['int', 'float', 'slide']:
|
|
622
|
-
if self.value() > limits[1]:
|
|
623
|
-
self.setValue(limits[1])
|
|
624
|
-
elif self.value() < limits[0]:
|
|
625
|
-
self.setValue(limits[0])
|
|
626
|
-
return limits
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
registerParameterType('int', SimpleParameterCustom, override=True)
|
|
630
|
-
registerParameterType('float', SimpleParameterCustom, override=True)
|
|
631
|
-
registerParameterType('bool', SimpleParameterCustom, override=True)
|
|
632
|
-
registerParameterType('bool_push', SimpleParameterCustom, override=True)
|
|
633
|
-
registerParameterType('led_push', SimpleParameterCustom, override=True)
|
|
634
|
-
registerParameterType('date_time', SimpleParameterCustom, override=True)
|
|
635
|
-
registerParameterType('date', SimpleParameterCustom, override=True)
|
|
636
|
-
registerParameterType('time', SimpleParameterCustom, override=True)
|
|
637
|
-
registerParameterType('led', SimpleParameterCustom, override=True)
|
|
638
|
-
registerParameterType('pixmap', SimpleParameterCustom, override=True)
|
|
639
|
-
registerParameterType('pixmap_check', SimpleParameterCustom, override=True)
|
|
640
|
-
registerParameterType('slide', SimpleParameterCustom, override=True)
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
registerParameterType('slide', SimpleParameterCustom , override=True)
|
|
644
|
-
|
|
645
|
-
class ListParameterItem_custom(pTypes.ListParameterItem):
|
|
646
|
-
"""
|
|
647
|
-
WidgetParameterItem subclass providing comboBox that lets the user select from a list of options.
|
|
648
|
-
|
|
649
|
-
"""
|
|
650
|
-
|
|
651
|
-
def __init__(self, param, depth):
|
|
652
|
-
super().__init__(param, depth)
|
|
653
|
-
if 'tip' in param.opts:
|
|
654
|
-
self.displayLabel.setToolTip(param.opts['tip'])
|
|
655
|
-
|
|
656
|
-
def makeWidget(self):
|
|
657
|
-
"""
|
|
658
|
-
Make a widget from self parameter options, connected to the buttonClicked function.
|
|
659
|
-
|
|
660
|
-
Returns
|
|
661
|
-
-------
|
|
662
|
-
w:widget
|
|
663
|
-
the initialized widget
|
|
664
|
-
|
|
665
|
-
See Also
|
|
666
|
-
--------
|
|
667
|
-
buttonClicked, limitsChanged,
|
|
668
|
-
"""
|
|
669
|
-
opts = self.param.opts
|
|
670
|
-
t = opts['type']
|
|
671
|
-
w = Combo_pb()
|
|
672
|
-
w.add_pb.clicked.connect(self.buttonClicked)
|
|
673
|
-
w.setMaximumHeight(20) # # set to match height of spin box and line edit
|
|
674
|
-
if 'show_pb' in opts:
|
|
675
|
-
w.add_pb.setVisible(opts['show_pb'])
|
|
676
|
-
else:
|
|
677
|
-
w.add_pb.setVisible(False)
|
|
678
|
-
if 'tip' in opts:
|
|
679
|
-
w.setToolTip(opts['tip'])
|
|
680
|
-
w.sigChanged = w.combo.currentIndexChanged
|
|
681
|
-
w.value = self.value
|
|
682
|
-
w.setValue = self.setValue
|
|
683
|
-
self.widget = w # # needs to be set before limits are changed
|
|
684
|
-
self.limitsChanged(self.param, self.param.opts['limits'])
|
|
685
|
-
if len(self.forward) > 0:
|
|
686
|
-
self.setValue(self.param.value())
|
|
687
|
-
return w
|
|
688
|
-
|
|
689
|
-
def value(self):
|
|
690
|
-
key = str(self.widget.combo.currentText())
|
|
691
|
-
return self.forward.get(key, None)
|
|
692
|
-
|
|
693
|
-
def setValue(self, val):
|
|
694
|
-
self.targetValue = val
|
|
695
|
-
if val not in self.reverse[0]:
|
|
696
|
-
self.widget.combo.setCurrentIndex(0)
|
|
697
|
-
else:
|
|
698
|
-
key = self.reverse[1][self.reverse[0].index(val)]
|
|
699
|
-
ind = self.widget.combo.findText(key)
|
|
700
|
-
self.widget.combo.setCurrentIndex(ind)
|
|
701
|
-
|
|
702
|
-
def limitsChanged(self, param, limits):
|
|
703
|
-
"""
|
|
704
|
-
Set up forward / reverse mappings for {name:value} limits dictionnary.
|
|
705
|
-
|
|
706
|
-
=============== ================================== ========================================
|
|
707
|
-
**Parameters** **Type** **Description**
|
|
708
|
-
*param* instance of pyqtgraph parameter Not used
|
|
709
|
-
*limits* dictionnary the limits dictionnary to be mapped
|
|
710
|
-
=============== ================================== ========================================
|
|
711
|
-
|
|
712
|
-
"""
|
|
713
|
-
|
|
714
|
-
if len(limits) == 0:
|
|
715
|
-
limits = [''] # # Can never have an empty list--there is always at least a singhe blank item.
|
|
716
|
-
|
|
717
|
-
self.forward, self.reverse = ListParameter_custom.mapping(limits)
|
|
718
|
-
try:
|
|
719
|
-
self.widget.blockSignals(True)
|
|
720
|
-
val = self.targetValue # asUnicode(self.widget.currentText())
|
|
721
|
-
|
|
722
|
-
self.widget.combo.clear()
|
|
723
|
-
for k in self.forward:
|
|
724
|
-
self.widget.combo.addItem(k)
|
|
725
|
-
if k == val:
|
|
726
|
-
self.widget.combo.setCurrentIndex(self.widget.count() - 1)
|
|
727
|
-
self.updateDisplayLabel()
|
|
728
|
-
finally:
|
|
729
|
-
self.widget.blockSignals(False)
|
|
730
|
-
|
|
731
|
-
def buttonClicked(self):
|
|
732
|
-
"""
|
|
733
|
-
|
|
|
734
|
-
| Append the self limits attributes an added parameter with string value.
|
|
735
|
-
| Update parameter and call the limitschanged method to map the added parameter.
|
|
736
|
-
|
|
737
|
-
See Also
|
|
738
|
-
--------
|
|
739
|
-
limitsChanged,
|
|
740
|
-
"""
|
|
741
|
-
if type(self.param.opts['limits']) == list:
|
|
742
|
-
text, ok = QtWidgets.QInputDialog.getText(None, "Enter a value to add to the parameter",
|
|
743
|
-
"String value:", QtWidgets.QLineEdit.Normal)
|
|
744
|
-
if ok and not (text == ""):
|
|
745
|
-
self.param.opts['limits'].append(text)
|
|
746
|
-
self.limitsChanged(self.param, self.param.opts['limits'])
|
|
747
|
-
self.param.setValue(text)
|
|
748
|
-
|
|
749
|
-
def optsChanged(self, param, opts):
|
|
750
|
-
"""
|
|
751
|
-
Called when any options are changed that are not name, value, default, or limits.
|
|
752
|
-
|
|
753
|
-
=============== ================================== =======================================
|
|
754
|
-
**Parameters** **Type** **Description**
|
|
755
|
-
*param* instance of pyqtgraph parameter The parameter to be checked
|
|
756
|
-
*opts* string list The option dictionnary to be checked
|
|
757
|
-
=============== ================================== =======================================
|
|
758
|
-
|
|
759
|
-
See Also
|
|
760
|
-
--------
|
|
761
|
-
optsChanged
|
|
762
|
-
"""
|
|
763
|
-
# print "opts changed:", opts
|
|
764
|
-
ParameterItem.optsChanged(self, param, opts)
|
|
765
|
-
|
|
766
|
-
if 'show_pb' in opts:
|
|
767
|
-
self.widget.add_pb.setVisible(opts['show_pb'])
|
|
768
|
-
if 'enabled' in opts:
|
|
769
|
-
self.widget.setEnabled(opts['enabled'])
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
class ListParameter_custom(pTypes.ListParameter):
|
|
773
|
-
"""
|
|
774
|
-
=============== =======================================
|
|
775
|
-
**Attributes** **Type**
|
|
776
|
-
*itemClass* instance of ListParameterItem_custom
|
|
777
|
-
*sigActivated* instance of pyqt Signal
|
|
778
|
-
=============== =======================================
|
|
779
|
-
"""
|
|
780
|
-
itemClass = ListParameterItem_custom
|
|
781
|
-
sigActivated = Signal(object)
|
|
782
|
-
|
|
783
|
-
def __init__(self, **opts):
|
|
784
|
-
super(ListParameter_custom, self).__init__(**opts)
|
|
785
|
-
|
|
786
|
-
def activate(self):
|
|
787
|
-
"""
|
|
788
|
-
Emit the Activated signal.
|
|
789
|
-
"""
|
|
790
|
-
self.sigActivated.emit(self)
|
|
791
|
-
self.emitStateChanged('activated', None)
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
registerParameterType('list', ListParameter_custom, override=True)
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
class Combo_pb(QtWidgets.QWidget):
|
|
798
|
-
|
|
799
|
-
def __init__(self, items=[]):
|
|
800
|
-
|
|
801
|
-
super(Combo_pb, self).__init__()
|
|
802
|
-
self.items = items
|
|
803
|
-
self.initUI()
|
|
804
|
-
self.count = self.combo.count
|
|
805
|
-
|
|
806
|
-
def initUI(self):
|
|
807
|
-
"""
|
|
808
|
-
Init the User Interface.
|
|
809
|
-
"""
|
|
810
|
-
self.hor_layout = QtWidgets.QHBoxLayout()
|
|
811
|
-
self.combo = QtWidgets.QComboBox()
|
|
812
|
-
self.combo.addItems(self.items)
|
|
813
|
-
self.add_pb = QtWidgets.QPushButton()
|
|
814
|
-
self.add_pb.setText("")
|
|
815
|
-
icon3 = QtGui.QIcon()
|
|
816
|
-
icon3.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Add2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
|
817
|
-
self.add_pb.setIcon(icon3)
|
|
818
|
-
self.hor_layout.addWidget(self.combo)
|
|
819
|
-
self.hor_layout.addWidget(self.add_pb)
|
|
820
|
-
self.hor_layout.setSpacing(0)
|
|
821
|
-
self.hor_layout.setContentsMargins(0, 0, 0, 0)
|
|
822
|
-
self.add_pb.setMaximumWidth(25)
|
|
823
|
-
self.setLayout(self.hor_layout)
|
|
824
|
-
self.currentText = self.combo.currentText
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
class TableParameterItem(WidgetParameterItem):
|
|
828
|
-
|
|
829
|
-
def __init__(self, param, depth):
|
|
830
|
-
pTypes.WidgetParameterItem.__init__(self, param, depth)
|
|
831
|
-
self.hideWidget = False
|
|
832
|
-
self.subItem = QtWidgets.QTreeWidgetItem()
|
|
833
|
-
self.addChild(self.subItem)
|
|
834
|
-
|
|
835
|
-
def treeWidgetChanged(self):
|
|
836
|
-
"""
|
|
837
|
-
Check for changement in the Widget tree.
|
|
838
|
-
"""
|
|
839
|
-
# # TODO: fix so that superclass method can be called
|
|
840
|
-
# # (WidgetParameter should just natively support this style)
|
|
841
|
-
# WidgetParameterItem.treeWidgetChanged(self)
|
|
842
|
-
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
|
|
843
|
-
self.treeWidget().setItemWidget(self.subItem, 0, self.widget)
|
|
844
|
-
|
|
845
|
-
# for now, these are copied from ParameterItem.treeWidgetChanged
|
|
846
|
-
self.setHidden(not self.param.opts.get('visible', True))
|
|
847
|
-
self.setExpanded(self.param.opts.get('expanded', True))
|
|
848
|
-
|
|
849
|
-
def makeWidget(self):
|
|
850
|
-
"""
|
|
851
|
-
Make and initialize an instance of Table_custom.
|
|
852
|
-
|
|
853
|
-
Returns
|
|
854
|
-
-------
|
|
855
|
-
table : instance of Table_custom.
|
|
856
|
-
The initialized table.
|
|
857
|
-
|
|
858
|
-
See Also
|
|
859
|
-
--------
|
|
860
|
-
Table_custom
|
|
861
|
-
"""
|
|
862
|
-
opts = self.param.opts
|
|
863
|
-
w = Table_custom()
|
|
864
|
-
if 'tip' in opts:
|
|
865
|
-
w.setToolTip(opts['tip'])
|
|
866
|
-
w.setColumnCount(2)
|
|
867
|
-
if 'header' in opts:
|
|
868
|
-
w.setHorizontalHeaderLabels(self.param.opts['header'])
|
|
869
|
-
if 'height' not in opts:
|
|
870
|
-
opts['height'] = 200
|
|
871
|
-
w.setMaximumHeight(opts['height'])
|
|
872
|
-
# self.table.setReadOnly(self.param.opts.get('readonly', False))
|
|
873
|
-
w.value = w.get_table_value
|
|
874
|
-
w.setValue = w.set_table_value
|
|
875
|
-
w.sigChanged = w.itemChanged
|
|
876
|
-
return w
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
class Table_custom(QtWidgets.QTableWidget):
|
|
880
|
-
"""
|
|
881
|
-
============== ===========================
|
|
882
|
-
*Attributes** **Type**
|
|
883
|
-
*valuechanged* instance of pyqt Signal
|
|
884
|
-
*QtWidgets* instance of QTableWidget
|
|
885
|
-
============== ===========================
|
|
886
|
-
"""
|
|
887
|
-
|
|
888
|
-
valuechanged = Signal(OrderedDict)
|
|
889
|
-
|
|
890
|
-
def __init__(self):
|
|
891
|
-
QtWidgets.QTableWidget.__init__(self)
|
|
892
|
-
|
|
893
|
-
def get_table_value(self):
|
|
894
|
-
"""
|
|
895
|
-
Get the contents of the self coursed table.
|
|
896
|
-
|
|
897
|
-
Returns
|
|
898
|
-
-------
|
|
899
|
-
data : ordered dictionnary
|
|
900
|
-
The getted values dictionnary.
|
|
901
|
-
"""
|
|
902
|
-
data = OrderedDict([])
|
|
903
|
-
for ind in range(self.rowCount()):
|
|
904
|
-
item0 = self.item(ind, 0)
|
|
905
|
-
item1 = self.item(ind, 1)
|
|
906
|
-
if item0 is not None and item1 is not None:
|
|
907
|
-
try:
|
|
908
|
-
data[item0.text()] = float(item1.text())
|
|
909
|
-
except Exception:
|
|
910
|
-
data[item0.text()] = item1.text()
|
|
911
|
-
return data
|
|
912
|
-
|
|
913
|
-
def set_table_value(self, data_dict):
|
|
914
|
-
"""
|
|
915
|
-
Set the data values dictionnary to the custom table.
|
|
916
|
-
|
|
917
|
-
=============== ====================== ================================================
|
|
918
|
-
**Parameters** **Type** **Description**
|
|
919
|
-
*data_dict* ordered dictionnary the contents to be stored in the custom table
|
|
920
|
-
=============== ====================== ================================================
|
|
921
|
-
"""
|
|
922
|
-
try:
|
|
923
|
-
self.setRowCount(len(data_dict))
|
|
924
|
-
self.setColumnCount(2)
|
|
925
|
-
for ind, (key, value) in enumerate(data_dict.items()):
|
|
926
|
-
item0 = QtWidgets.QTableWidgetItem(key)
|
|
927
|
-
item0.setFlags(item0.flags() ^ Qt.ItemIsEditable)
|
|
928
|
-
if isinstance(value, float):
|
|
929
|
-
item1 = QtWidgets.QTableWidgetItem('{:.6e}'.format(value))
|
|
930
|
-
else:
|
|
931
|
-
item1 = QtWidgets.QTableWidgetItem(str(value))
|
|
932
|
-
item1.setFlags(item1.flags() ^ Qt.ItemIsEditable)
|
|
933
|
-
self.setItem(ind, 0, item0)
|
|
934
|
-
self.setItem(ind, 1, item1)
|
|
935
|
-
# self.valuechanged.emit(data_dict)
|
|
936
|
-
|
|
937
|
-
except Exception as e:
|
|
938
|
-
pass
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
class TableParameter(Parameter):
|
|
942
|
-
"""
|
|
943
|
-
=============== =================================
|
|
944
|
-
**Attributes** **Type**
|
|
945
|
-
*itemClass* instance of TableParameterItem
|
|
946
|
-
*Parameter* instance of pyqtgraph parameter
|
|
947
|
-
=============== =================================
|
|
948
|
-
"""
|
|
949
|
-
itemClass = TableParameterItem
|
|
950
|
-
"""Editable string; displayed as large text box in the tree."""
|
|
951
|
-
|
|
952
|
-
# def __init(self):
|
|
953
|
-
# super(TableParameter,self).__init__()
|
|
954
|
-
|
|
955
|
-
def setValue(self, value):
|
|
956
|
-
self.opts['value'] = value
|
|
957
|
-
self.sigValueChanged.emit(self, value)
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
registerParameterType('table', TableParameter, override=True)
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
class TableViewParameterItem(WidgetParameterItem):
|
|
964
|
-
def __init__(self, param, depth):
|
|
965
|
-
pTypes.WidgetParameterItem.__init__(self, param, depth)
|
|
966
|
-
self.hideWidget = False
|
|
967
|
-
self.subItem = QtWidgets.QTreeWidgetItem()
|
|
968
|
-
self.addChild(self.subItem)
|
|
969
|
-
|
|
970
|
-
def treeWidgetChanged(self):
|
|
971
|
-
"""
|
|
972
|
-
Check for changement in the Widget tree.
|
|
973
|
-
"""
|
|
974
|
-
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
|
|
975
|
-
self.treeWidget().setItemWidget(self.subItem, 0, self.widget)
|
|
976
|
-
|
|
977
|
-
# for now, these are copied from ParameterItem.treeWidgetChanged
|
|
978
|
-
self.setHidden(not self.param.opts.get('visible', True))
|
|
979
|
-
self.setExpanded(self.param.opts.get('expanded', True))
|
|
980
|
-
|
|
981
|
-
def makeWidget(self):
|
|
982
|
-
"""
|
|
983
|
-
Make and initialize an instance of Table_custom.
|
|
984
|
-
|
|
985
|
-
Returns
|
|
986
|
-
-------
|
|
987
|
-
table : instance of Table_custom.
|
|
988
|
-
The initialized table.
|
|
989
|
-
|
|
990
|
-
See Also
|
|
991
|
-
--------
|
|
992
|
-
Table_custom
|
|
993
|
-
"""
|
|
994
|
-
menu = False
|
|
995
|
-
opts = self.param.opts
|
|
996
|
-
if 'menu' in opts:
|
|
997
|
-
menu = opts['menu']
|
|
998
|
-
w = TableViewCustom(menu=menu)
|
|
999
|
-
|
|
1000
|
-
if 'tip' in opts:
|
|
1001
|
-
w.setToolTip(opts['tip'])
|
|
1002
|
-
|
|
1003
|
-
w.setMaximumHeight(200)
|
|
1004
|
-
# self.table.setReadOnly(self.param.opts.get('readonly', False))
|
|
1005
|
-
w.value = w.get_table_value
|
|
1006
|
-
w.setValue = w.set_table_value
|
|
1007
|
-
w.sigChanged = w.valueChanged
|
|
1008
|
-
return w
|
|
1009
|
-
|
|
1010
|
-
def optsChanged(self, param, opts):
|
|
1011
|
-
"""
|
|
1012
|
-
| Called when any options are changed that are not name, value, default, or limits.
|
|
1013
|
-
|
|
|
1014
|
-
| If widget is a SpinBox, pass options straight through.
|
|
1015
|
-
| So that only the display label is shown when visible option is toggled.
|
|
1016
|
-
|
|
1017
|
-
=============== ================================== ==============================
|
|
1018
|
-
**Parameters** **Type** **Description**
|
|
1019
|
-
*param* instance of pyqtgraph parameter the parameter to check
|
|
1020
|
-
*opts* string list the associated options list
|
|
1021
|
-
=============== ================================== ==============================
|
|
1022
|
-
|
|
1023
|
-
See Also
|
|
1024
|
-
--------
|
|
1025
|
-
optsChanged
|
|
1026
|
-
"""
|
|
1027
|
-
# print "opts changed:", opts
|
|
1028
|
-
ParameterItem.optsChanged(self, param, opts)
|
|
1029
|
-
|
|
1030
|
-
if 'readonly' in opts:
|
|
1031
|
-
self.updateDefaultBtn()
|
|
1032
|
-
if isinstance(self.widget, (QtWidgets.QCheckBox, ColorButton.ColorButton)):
|
|
1033
|
-
self.widget.setEnabled(not opts['readonly'])
|
|
1034
|
-
|
|
1035
|
-
if 'delegate' in opts:
|
|
1036
|
-
styledItemDelegate = QtWidgets.QStyledItemDelegate()
|
|
1037
|
-
styledItemDelegate.setItemEditorFactory(opts['delegate']())
|
|
1038
|
-
self.widget.setItemDelegate(styledItemDelegate)
|
|
1039
|
-
|
|
1040
|
-
if 'menu' in opts:
|
|
1041
|
-
self.widget.setmenu(opts['menu'])
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
class TableViewCustom(QtWidgets.QTableView):
|
|
1045
|
-
"""
|
|
1046
|
-
============== ===========================
|
|
1047
|
-
*Attributes** **Type**
|
|
1048
|
-
*valuechanged* instance of pyqt Signal
|
|
1049
|
-
*QtWidgets* instance of QTableWidget
|
|
1050
|
-
============== ===========================
|
|
1051
|
-
"""
|
|
1052
|
-
|
|
1053
|
-
valueChanged = Signal(list)
|
|
1054
|
-
add_data_signal = Signal(int)
|
|
1055
|
-
remove_row_signal = Signal(int)
|
|
1056
|
-
load_data_signal = Signal()
|
|
1057
|
-
save_data_signal = Signal()
|
|
1058
|
-
|
|
1059
|
-
def __init__(self, menu=False):
|
|
1060
|
-
super().__init__()
|
|
1061
|
-
self.setmenu(menu)
|
|
1062
|
-
|
|
1063
|
-
def setmenu(self, status):
|
|
1064
|
-
if status:
|
|
1065
|
-
self.menu = QtWidgets.QMenu()
|
|
1066
|
-
self.menu.addAction('Add new', self.add)
|
|
1067
|
-
self.menu.addAction('Remove selected row', self.remove)
|
|
1068
|
-
self.menu.addAction('Clear all', self.clear)
|
|
1069
|
-
self.menu.addSeparator()
|
|
1070
|
-
self.menu.addAction('Load as txt', lambda: self.load_data_signal.emit())
|
|
1071
|
-
self.menu.addAction('Save as txt', lambda: self.save_data_signal.emit())
|
|
1072
|
-
else:
|
|
1073
|
-
self.menu = None
|
|
1074
|
-
|
|
1075
|
-
def clear(self):
|
|
1076
|
-
self.model().clear()
|
|
1077
|
-
|
|
1078
|
-
def add(self):
|
|
1079
|
-
self.add_data_signal.emit(self.currentIndex().row())
|
|
1080
|
-
|
|
1081
|
-
def remove(self):
|
|
1082
|
-
self.remove_row_signal.emit(self.currentIndex().row())
|
|
1083
|
-
|
|
1084
|
-
def data_has_changed(self, topleft, bottomright, roles):
|
|
1085
|
-
self.valueChanged.emit([topleft, bottomright, roles])
|
|
1086
|
-
|
|
1087
|
-
def get_table_value(self):
|
|
1088
|
-
"""
|
|
1089
|
-
|
|
1090
|
-
"""
|
|
1091
|
-
return self.model()
|
|
1092
|
-
|
|
1093
|
-
def set_table_value(self, data_model):
|
|
1094
|
-
"""
|
|
1095
|
-
|
|
1096
|
-
"""
|
|
1097
|
-
try:
|
|
1098
|
-
self.setModel(data_model)
|
|
1099
|
-
self.model().dataChanged.connect(self.data_has_changed)
|
|
1100
|
-
except Exception as e:
|
|
1101
|
-
pass
|
|
1102
|
-
|
|
1103
|
-
def contextMenuEvent(self, event):
|
|
1104
|
-
if self.menu is not None:
|
|
1105
|
-
self.menu.exec(event.globalPos())
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
class TableViewParameter(Parameter):
|
|
1109
|
-
"""
|
|
1110
|
-
=============== =================================
|
|
1111
|
-
**Attributes** **Type**
|
|
1112
|
-
*itemClass* instance of TableParameterItem
|
|
1113
|
-
*Parameter* instance of pyqtgraph parameter
|
|
1114
|
-
=============== =================================
|
|
1115
|
-
"""
|
|
1116
|
-
itemClass = TableViewParameterItem
|
|
1117
|
-
|
|
1118
|
-
def setValue(self, value):
|
|
1119
|
-
self.opts['value'] = value
|
|
1120
|
-
self.sigValueChanged.emit(self, value)
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
registerParameterType('table_view', TableViewParameter, override=True)
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
class ItemSelectParameterItem(WidgetParameterItem):
|
|
1127
|
-
|
|
1128
|
-
def __init__(self, param, depth):
|
|
1129
|
-
pTypes.WidgetParameterItem.__init__(self, param, depth)
|
|
1130
|
-
self.hideWidget = False
|
|
1131
|
-
self.subItem = QtWidgets.QTreeWidgetItem()
|
|
1132
|
-
self.addChild(self.subItem)
|
|
1133
|
-
|
|
1134
|
-
def treeWidgetChanged(self):
|
|
1135
|
-
"""
|
|
1136
|
-
|
|
1137
|
-
"""
|
|
1138
|
-
# # TODO: fix so that superclass method can be called
|
|
1139
|
-
# # (WidgetParameter should just natively support this style)
|
|
1140
|
-
# WidgetParameterItem.treeWidgetChanged(self)
|
|
1141
|
-
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
|
|
1142
|
-
self.treeWidget().setItemWidget(self.subItem, 0, self.widget)
|
|
1143
|
-
|
|
1144
|
-
# for now, these are copied from ParameterItem.treeWidgetChanged
|
|
1145
|
-
self.setHidden(not self.param.opts.get('visible', True))
|
|
1146
|
-
self.setExpanded(self.param.opts.get('expanded', True))
|
|
1147
|
-
|
|
1148
|
-
def makeWidget(self):
|
|
1149
|
-
"""
|
|
1150
|
-
| Make and initialize an instance of ItemSelect_pb with itemselect value.
|
|
1151
|
-
| Connect the created object with the buttonClicked function.
|
|
1152
|
-
|
|
1153
|
-
"""
|
|
1154
|
-
opts = self.param.opts
|
|
1155
|
-
w = ItemSelect_pb()
|
|
1156
|
-
w.itemselect.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
|
1157
|
-
if 'height' in opts:
|
|
1158
|
-
w.itemselect.setMaximumHeight(opts['height'])
|
|
1159
|
-
else:
|
|
1160
|
-
w.itemselect.setMaximumHeight(70)
|
|
1161
|
-
# w.setReadOnly(self.param.opts.get('readonly', False))
|
|
1162
|
-
if 'show_pb' in opts:
|
|
1163
|
-
w.add_pb.setVisible(opts['show_pb'])
|
|
1164
|
-
else:
|
|
1165
|
-
w.add_pb.setVisible(False)
|
|
1166
|
-
if 'tip' in opts:
|
|
1167
|
-
w.setToolTip(opts['tip'])
|
|
1168
|
-
w.value = w.itemselect.get_value
|
|
1169
|
-
w.setValue = w.itemselect.set_value
|
|
1170
|
-
w.sigChanged = w.itemselect.itemSelectionChanged
|
|
1171
|
-
w.add_pb.clicked.connect(self.buttonClicked)
|
|
1172
|
-
return w
|
|
1173
|
-
|
|
1174
|
-
def buttonClicked(self):
|
|
1175
|
-
"""
|
|
1176
|
-
Append to the param attribute the dictionnary obtained from the QtWidget add parameter procedure.
|
|
1177
|
-
"""
|
|
1178
|
-
|
|
1179
|
-
text, ok = QtWidgets.QInputDialog.getText(None, "Enter a value to add to the parameter",
|
|
1180
|
-
"String value:", QtWidgets.QLineEdit.Normal)
|
|
1181
|
-
if ok and not (text == ""):
|
|
1182
|
-
all = self.param.value()['all_items']
|
|
1183
|
-
all.append(text)
|
|
1184
|
-
sel = self.param.value()['selected']
|
|
1185
|
-
sel.append(text)
|
|
1186
|
-
val = dict(all_items=all, selected=sel)
|
|
1187
|
-
self.param.setValue(val)
|
|
1188
|
-
self.param.sigValueChanged.emit(self.param, val)
|
|
1189
|
-
|
|
1190
|
-
def optsChanged(self, param, opts):
|
|
1191
|
-
"""
|
|
1192
|
-
Called when any options are changed that are not name, value, default, or limits.
|
|
1193
|
-
|
|
1194
|
-
See Also
|
|
1195
|
-
--------
|
|
1196
|
-
optsChanged
|
|
1197
|
-
"""
|
|
1198
|
-
# print "opts changed:", opts
|
|
1199
|
-
ParameterItem.optsChanged(self, param, opts)
|
|
1200
|
-
|
|
1201
|
-
if 'show_pb' in opts:
|
|
1202
|
-
self.widget.add_pb.setVisible(opts['show_pb'])
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
class ItemSelect_pb(QtWidgets.QWidget):
|
|
1206
|
-
def __init__(self):
|
|
1207
|
-
|
|
1208
|
-
super(ItemSelect_pb, self).__init__()
|
|
1209
|
-
self.initUI()
|
|
1210
|
-
|
|
1211
|
-
def initUI(self):
|
|
1212
|
-
self.hor_layout = QtWidgets.QHBoxLayout()
|
|
1213
|
-
self.itemselect = ItemSelect()
|
|
1214
|
-
self.add_pb = QtWidgets.QPushButton()
|
|
1215
|
-
self.add_pb.setText("")
|
|
1216
|
-
icon3 = QtGui.QIcon()
|
|
1217
|
-
icon3.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Add2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
|
1218
|
-
self.add_pb.setIcon(icon3)
|
|
1219
|
-
self.hor_layout.addWidget(self.itemselect)
|
|
1220
|
-
self.hor_layout.addWidget(self.add_pb)
|
|
1221
|
-
self.hor_layout.setSpacing(0)
|
|
1222
|
-
|
|
1223
|
-
self.setLayout(self.hor_layout)
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
class ItemSelect(QtWidgets.QListWidget):
|
|
1227
|
-
def __init__(self):
|
|
1228
|
-
QtWidgets.QListWidget.__init__(self)
|
|
1229
|
-
|
|
1230
|
-
def get_value(self):
|
|
1231
|
-
"""
|
|
1232
|
-
Get the dictionnary of values contained in the QtWidget attribute.
|
|
1233
|
-
|
|
1234
|
-
Returns
|
|
1235
|
-
-------
|
|
1236
|
-
dictionnary
|
|
1237
|
-
The dictionnary of all_items compared to the slelectedItems.
|
|
1238
|
-
"""
|
|
1239
|
-
selitems = [item.text() for item in self.selectedItems()]
|
|
1240
|
-
allitems = [item.text() for item in self.all_items()]
|
|
1241
|
-
return dict(all_items=allitems, selected=selitems)
|
|
1242
|
-
|
|
1243
|
-
def all_items(self):
|
|
1244
|
-
"""
|
|
1245
|
-
Get the all_items list from the self QtWidget attribute.
|
|
1246
|
-
|
|
1247
|
-
Returns
|
|
1248
|
-
-------
|
|
1249
|
-
list
|
|
1250
|
-
The item list.
|
|
1251
|
-
"""
|
|
1252
|
-
return [self.item(ind) for ind in range(self.count())]
|
|
1253
|
-
|
|
1254
|
-
def set_value(self, values):
|
|
1255
|
-
"""
|
|
1256
|
-
Set values to the all_items attributes filtering values by the 'selected' key.
|
|
1257
|
-
|
|
1258
|
-
=============== ============== =======================================
|
|
1259
|
-
**Parameters** **Type** **Description**
|
|
1260
|
-
*values* dictionnary the values dictionnary to be setted.
|
|
1261
|
-
=============== ============== =======================================
|
|
1262
|
-
"""
|
|
1263
|
-
allitems = [item.text() for item in self.all_items()]
|
|
1264
|
-
if allitems != values['all_items']:
|
|
1265
|
-
self.clear()
|
|
1266
|
-
self.addItems(values['all_items'])
|
|
1267
|
-
QtWidgets.QApplication.processEvents()
|
|
1268
|
-
for item in self.all_items():
|
|
1269
|
-
if item.text() in values['selected']:
|
|
1270
|
-
item.setSelected(True)
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
class ItemSelectParameter(Parameter):
|
|
1274
|
-
"""
|
|
1275
|
-
Editable string; displayed as large text box in the tree.
|
|
1276
|
-
|
|
1277
|
-
=============== ======================================
|
|
1278
|
-
**Attributes** **Type**
|
|
1279
|
-
*itemClass* instance of ItemSelectParameterItem
|
|
1280
|
-
*sigActivated* instance of pyqt Signal
|
|
1281
|
-
=============== ======================================
|
|
1282
|
-
"""
|
|
1283
|
-
itemClass = ItemSelectParameterItem
|
|
1284
|
-
sigActivated = Signal(object)
|
|
1285
|
-
|
|
1286
|
-
def activate(self):
|
|
1287
|
-
"""
|
|
1288
|
-
Activate the "Activated" signal attribute0
|
|
1289
|
-
"""
|
|
1290
|
-
self.sigActivated.emit(self)
|
|
1291
|
-
self.emitStateChanged('activated', None)
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
registerParameterType('itemselect', ItemSelectParameter, override=True)
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
class ActionParameterItem(pTypes.ActionParameterItem):
|
|
1298
|
-
def __init__(self, param, depth):
|
|
1299
|
-
super().__init__(param, depth)
|
|
1300
|
-
|
|
1301
|
-
if 'title' in param.opts:
|
|
1302
|
-
name = param.opts['title']
|
|
1303
|
-
else:
|
|
1304
|
-
name = param.name()
|
|
1305
|
-
self.button.setText(name)
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
class ActionParameter(pTypes.ActionParameter):
|
|
1309
|
-
"""Used for displaying a button within the tree."""
|
|
1310
|
-
itemClass = ActionParameterItem
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
registerParameterType('action', ActionParameter, override=True)
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
class file_browserParameterItem(WidgetParameterItem):
|
|
1317
|
-
|
|
1318
|
-
def __init__(self, param, depth):
|
|
1319
|
-
self.filetype = False
|
|
1320
|
-
super().__init__(param, depth)
|
|
1321
|
-
self.hideWidget = False
|
|
1322
|
-
self.subItem = QtWidgets.QTreeWidgetItem()
|
|
1323
|
-
self.addChild(self.subItem)
|
|
1324
|
-
|
|
1325
|
-
def treeWidgetChanged(self):
|
|
1326
|
-
# # TODO: fix so that superclass method can be called
|
|
1327
|
-
# # (WidgetParameter should just natively support this style)
|
|
1328
|
-
# WidgetParameterItem.treeWidgetChanged(self)
|
|
1329
|
-
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
|
|
1330
|
-
self.treeWidget().setItemWidget(self.subItem, 0, self.w)
|
|
1331
|
-
|
|
1332
|
-
# for now, these are copied from ParameterItem.treeWidgetChanged
|
|
1333
|
-
self.setHidden(not self.param.opts.get('visible', True))
|
|
1334
|
-
self.setExpanded(self.param.opts.get('expanded', True))
|
|
1335
|
-
|
|
1336
|
-
def makeWidget(self):
|
|
1337
|
-
"""
|
|
1338
|
-
Make an initialized file_browser object with parameter options dictionnary ('readonly' key)0
|
|
1339
|
-
|
|
1340
|
-
Returns
|
|
1341
|
-
-------
|
|
1342
|
-
w : filebrowser
|
|
1343
|
-
The initialized file browser.
|
|
1344
|
-
|
|
1345
|
-
See Also
|
|
1346
|
-
--------
|
|
1347
|
-
file_browser
|
|
1348
|
-
"""
|
|
1349
|
-
if 'filetype' in self.param.opts:
|
|
1350
|
-
self.filetype = self.param.opts['filetype']
|
|
1351
|
-
else:
|
|
1352
|
-
self.filetype = True
|
|
1353
|
-
|
|
1354
|
-
self.w = file_browser(self.param.value(), file_type=self.filetype)
|
|
1355
|
-
if 'tip' in self.param.opts:
|
|
1356
|
-
self.w.setToolTip(self.param.opts['tip'])
|
|
1357
|
-
# self.file_browser.setMaximumHeight(100)
|
|
1358
|
-
self.w.base_path_edit.setReadOnly(self.param.opts['readonly'])
|
|
1359
|
-
self.w.value = self.w.get_value
|
|
1360
|
-
self.w.setValue = self.w.set_path
|
|
1361
|
-
self.w.sigChanged = self.w.value_changed
|
|
1362
|
-
return self.w
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
class file_browser(QtWidgets.QWidget):
|
|
1366
|
-
"""
|
|
1367
|
-
================ =========================
|
|
1368
|
-
**Attributes** **Type**
|
|
1369
|
-
*value_changed* instance of pyqt Signal
|
|
1370
|
-
*path* string
|
|
1371
|
-
================ =========================
|
|
1372
|
-
|
|
1373
|
-
See Also
|
|
1374
|
-
--------
|
|
1375
|
-
browse_path
|
|
1376
|
-
"""
|
|
1377
|
-
value_changed = Signal(str)
|
|
1378
|
-
|
|
1379
|
-
def __init__(self, init_path='D:/Data', file_type=False):
|
|
1380
|
-
|
|
1381
|
-
super(file_browser, self).__init__()
|
|
1382
|
-
self.filetype = file_type
|
|
1383
|
-
self.path = init_path
|
|
1384
|
-
self.initUI()
|
|
1385
|
-
|
|
1386
|
-
self.base_path_browse_pb.clicked.connect(self.browse_path)
|
|
1387
|
-
|
|
1388
|
-
def browse_path(self):
|
|
1389
|
-
"""
|
|
1390
|
-
Browse the path attribute if exist.
|
|
1391
|
-
|
|
1392
|
-
See Also
|
|
1393
|
-
--------
|
|
1394
|
-
set_path
|
|
1395
|
-
"""
|
|
1396
|
-
if self.filetype is True:
|
|
1397
|
-
folder_name = QtWidgets.QFileDialog.getOpenFileName(None, 'Choose File', os.path.split(self.path)[0])[0]
|
|
1398
|
-
elif self.filetype is False:
|
|
1399
|
-
folder_name = QtWidgets.QFileDialog.getExistingDirectory(None, 'Choose Folder', self.path)
|
|
1400
|
-
|
|
1401
|
-
elif self.filetype == "save":
|
|
1402
|
-
folder_name = QtWidgets.QFileDialog.getSaveFileName(None, 'Enter a Filename', os.path.split(self.path)[0])[
|
|
1403
|
-
0]
|
|
1404
|
-
|
|
1405
|
-
if not (not (folder_name)): # execute if the user didn't cancel the file selection
|
|
1406
|
-
self.set_path(folder_name)
|
|
1407
|
-
self.value_changed.emit(folder_name)
|
|
1408
|
-
|
|
1409
|
-
def set_path(self, path_file):
|
|
1410
|
-
"""
|
|
1411
|
-
Set the base path attribute with the given path_file.
|
|
1412
|
-
|
|
1413
|
-
=============== =========== ===========================
|
|
1414
|
-
**Parameters** **Type** **Description**
|
|
1415
|
-
*path_file* string the pathname of the file
|
|
1416
|
-
=============== =========== ===========================
|
|
1417
|
-
"""
|
|
1418
|
-
if isinstance(path_file, Path):
|
|
1419
|
-
path_file = str(path_file)
|
|
1420
|
-
self.base_path_edit.setPlainText(path_file)
|
|
1421
|
-
self.path = path_file
|
|
1422
|
-
|
|
1423
|
-
def get_value(self):
|
|
1424
|
-
"""
|
|
1425
|
-
Get the value of the base_path_edit attribute.
|
|
1426
|
-
|
|
1427
|
-
Returns
|
|
1428
|
-
-------
|
|
1429
|
-
string
|
|
1430
|
-
the path name
|
|
1431
|
-
"""
|
|
1432
|
-
return self.base_path_edit.toPlainText()
|
|
1433
|
-
|
|
1434
|
-
def initUI(self):
|
|
1435
|
-
"""
|
|
1436
|
-
Init the User Interface.
|
|
1437
|
-
"""
|
|
1438
|
-
|
|
1439
|
-
self.hor_layout = QtWidgets.QHBoxLayout()
|
|
1440
|
-
self.base_path_edit = QtWidgets.QPlainTextEdit(self.path)
|
|
1441
|
-
self.base_path_edit.setMaximumHeight(50)
|
|
1442
|
-
self.base_path_browse_pb = QtWidgets.QPushButton()
|
|
1443
|
-
self.base_path_browse_pb.setText("")
|
|
1444
|
-
icon3 = QtGui.QIcon()
|
|
1445
|
-
icon3.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Browse_Dir_Path.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
|
1446
|
-
self.base_path_browse_pb.setIcon(icon3)
|
|
1447
|
-
self.hor_layout.addWidget(self.base_path_edit)
|
|
1448
|
-
|
|
1449
|
-
verlayout = QtWidgets.QVBoxLayout()
|
|
1450
|
-
verlayout.addWidget(self.base_path_browse_pb)
|
|
1451
|
-
verlayout.addStretch()
|
|
1452
|
-
self.hor_layout.addLayout(verlayout)
|
|
1453
|
-
self.hor_layout.setSpacing(0)
|
|
1454
|
-
self.setLayout(self.hor_layout)
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
class file_browserParameter(Parameter):
|
|
1458
|
-
"""
|
|
1459
|
-
Editable string; displayed as large text box in the tree.
|
|
1460
|
-
See Also
|
|
1461
|
-
--------
|
|
1462
|
-
file_browserParameterItem
|
|
1463
|
-
"""
|
|
1464
|
-
itemClass = file_browserParameterItem
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
registerParameterType('browsepath', file_browserParameter, override=True)
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
class Plain_text_pbParameterItem(pTypes.WidgetParameterItem):
|
|
1471
|
-
|
|
1472
|
-
def __init__(self, param, depth):
|
|
1473
|
-
pTypes.WidgetParameterItem.__init__(self, param, depth)
|
|
1474
|
-
self.hideWidget = False
|
|
1475
|
-
self.subItem = QtWidgets.QTreeWidgetItem()
|
|
1476
|
-
self.addChild(self.subItem)
|
|
1477
|
-
|
|
1478
|
-
def treeWidgetChanged(self):
|
|
1479
|
-
# # TODO: fix so that superclass method can be called
|
|
1480
|
-
# # (WidgetParameter should just natively support this style)
|
|
1481
|
-
# WidgetParameterItem.treeWidgetChanged(self)
|
|
1482
|
-
self.treeWidget().setFirstItemColumnSpanned(self.subItem, True)
|
|
1483
|
-
self.treeWidget().setItemWidget(self.subItem, 0, self.w)
|
|
1484
|
-
|
|
1485
|
-
# for now, these are copied from ParameterItem.treeWidgetChanged
|
|
1486
|
-
self.setHidden(not self.param.opts.get('visible', True))
|
|
1487
|
-
self.setExpanded(self.param.opts.get('expanded', True))
|
|
1488
|
-
|
|
1489
|
-
def makeWidget(self):
|
|
1490
|
-
"""
|
|
1491
|
-
Make and initialize an instance of Plain_text_pb object from parameter options dictionnary (using 'readonly' key).
|
|
1492
|
-
|
|
1493
|
-
Returns
|
|
1494
|
-
-------
|
|
1495
|
-
Plain_text_pb object
|
|
1496
|
-
The initialized object.
|
|
1497
|
-
|
|
1498
|
-
See Also
|
|
1499
|
-
--------
|
|
1500
|
-
Plain_text_pb, buttonClicked
|
|
1501
|
-
"""
|
|
1502
|
-
self.w = Plain_text_pb()
|
|
1503
|
-
self.w.text_edit.setReadOnly(self.param.opts.get('readonly', False))
|
|
1504
|
-
self.w.value = self.w.get_value
|
|
1505
|
-
self.w.setValue = self.w.set_value
|
|
1506
|
-
self.w.sigChanged = self.w.value_changed
|
|
1507
|
-
self.w.add_pb.clicked.connect(self.buttonClicked)
|
|
1508
|
-
return self.w
|
|
1509
|
-
|
|
1510
|
-
def buttonClicked(self):
|
|
1511
|
-
text, ok = QtWidgets.QInputDialog.getText(None, "Enter a value to add to the parameter",
|
|
1512
|
-
"String value:", QtWidgets.QLineEdit.Normal)
|
|
1513
|
-
if ok and not (text == ""):
|
|
1514
|
-
self.param.setValue(self.param.value() + '\n' + text)
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
class Plain_text_pb(QtWidgets.QWidget):
|
|
1518
|
-
"""
|
|
1519
|
-
================ ========================
|
|
1520
|
-
**Attributes** **Type**
|
|
1521
|
-
*value_changed* instance of pyqt Signal
|
|
1522
|
-
================ ========================
|
|
1523
|
-
|
|
1524
|
-
See Also
|
|
1525
|
-
--------
|
|
1526
|
-
initUI, emitsignal
|
|
1527
|
-
"""
|
|
1528
|
-
value_changed = Signal(str)
|
|
1529
|
-
|
|
1530
|
-
def __init__(self):
|
|
1531
|
-
|
|
1532
|
-
super(Plain_text_pb, self).__init__()
|
|
1533
|
-
|
|
1534
|
-
self.initUI()
|
|
1535
|
-
self.text_edit.textChanged.connect(self.emitsignal)
|
|
1536
|
-
|
|
1537
|
-
def emitsignal(self):
|
|
1538
|
-
"""
|
|
1539
|
-
Emit the value changed signal from the text_edit attribute.
|
|
1540
|
-
"""
|
|
1541
|
-
text = self.text_edit.toPlainText()
|
|
1542
|
-
self.value_changed.emit(text)
|
|
1543
|
-
|
|
1544
|
-
def set_value(self, txt):
|
|
1545
|
-
"""
|
|
1546
|
-
Set the value of the text_edit attribute.
|
|
1547
|
-
|
|
1548
|
-
=============== =========== ================================
|
|
1549
|
-
**Parameters** **Type** **Description**
|
|
1550
|
-
*txt* string the string value to be setted
|
|
1551
|
-
=============== =========== ================================
|
|
1552
|
-
"""
|
|
1553
|
-
self.text_edit.setPlainText(txt)
|
|
1554
|
-
|
|
1555
|
-
def get_value(self):
|
|
1556
|
-
"""
|
|
1557
|
-
Get the value of the text_edit attribute.
|
|
1558
|
-
|
|
1559
|
-
Returns
|
|
1560
|
-
-------
|
|
1561
|
-
string
|
|
1562
|
-
The string value of text_edit.
|
|
1563
|
-
"""
|
|
1564
|
-
return self.text_edit.toPlainText()
|
|
1565
|
-
|
|
1566
|
-
def initUI(self):
|
|
1567
|
-
"""
|
|
1568
|
-
Init the User Interface.
|
|
1569
|
-
"""
|
|
1570
|
-
|
|
1571
|
-
self.hor_layout = QtWidgets.QHBoxLayout()
|
|
1572
|
-
self.text_edit = QtWidgets.QPlainTextEdit()
|
|
1573
|
-
self.text_edit.setReadOnly(True)
|
|
1574
|
-
self.text_edit.setMaximumHeight(50)
|
|
1575
|
-
|
|
1576
|
-
self.add_pb = QtWidgets.QPushButton()
|
|
1577
|
-
self.add_pb.setText("")
|
|
1578
|
-
icon3 = QtGui.QIcon()
|
|
1579
|
-
icon3.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Add2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
|
1580
|
-
self.add_pb.setIcon(icon3)
|
|
1581
|
-
self.hor_layout.addWidget(self.text_edit)
|
|
1582
|
-
|
|
1583
|
-
verlayout = QtWidgets.QVBoxLayout()
|
|
1584
|
-
verlayout.addWidget(self.add_pb)
|
|
1585
|
-
verlayout.addStretch()
|
|
1586
|
-
self.hor_layout.addLayout(verlayout)
|
|
1587
|
-
self.hor_layout.setSpacing(0)
|
|
1588
|
-
self.setLayout(self.hor_layout)
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
class Plain_text_pbParameter(Parameter):
|
|
1592
|
-
"""Editable string; displayed as large text box in the tree."""
|
|
1593
|
-
itemClass = Plain_text_pbParameterItem
|
|
1594
|
-
sigActivated = Signal(object)
|
|
1595
|
-
|
|
1596
|
-
def activate(self):
|
|
1597
|
-
"""
|
|
1598
|
-
Send the Activated signal.
|
|
1599
|
-
"""
|
|
1600
|
-
self.sigActivated.emit(self)
|
|
1601
|
-
self.emitStateChanged('activated', None)
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
registerParameterType('text_pb', Plain_text_pbParameter, override=True)
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
class TextParameterItemCustom(pTypes.TextParameterItem):
|
|
1608
|
-
def __init__(self, param, depth):
|
|
1609
|
-
super(TextParameterItemCustom, self).__init__(param, depth)
|
|
1610
|
-
|
|
1611
|
-
self.textBox.setMaximumHeight(50)
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
class TextParameter(Parameter):
|
|
1615
|
-
"""Editable string; displayed as large text box in the tree."""
|
|
1616
|
-
itemClass = TextParameterItemCustom
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
registerParameterType('text', TextParameter, override=True)
|
|
1620
|
-
|
|
1621
|
-
if __name__ == '__main__':
|
|
1622
|
-
app = QtWidgets.QApplication(sys.argv)
|
|
1623
|
-
ex = QTimeCustom()
|
|
1624
|
-
ex.setMinuteIncrement(30)
|
|
1625
|
-
ex.show()
|
|
1626
|
-
sys.exit(app.exec_())
|