source: sasview/src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py @ d3c0b95

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since d3c0b95 was d6b8a1d, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

More Qt5 related fixes

  • Property mode set to 100644
File size: 7.0 KB
Line 
1"""
2Widget/logic for smearing data.
3"""
4import numpy as np
5from PyQt5 import QtCore
6from PyQt5 import QtGui
7from PyQt5 import QtWidgets
8
9from sas.qtgui.Plotting.PlotterData import Data2D
10import sas.qtgui.Utilities.GuiUtils as GuiUtils
11
12# Local UI
13from sas.qtgui.Perspectives.Fitting.UI.OptionsWidgetUI import Ui_tabOptions
14
15QMIN_DEFAULT = 0.0005
16QMAX_DEFAULT = 0.5
17NPTS_DEFAULT = 50
18
19MODEL = [
20    'MIN_RANGE',
21    'MAX_RANGE',
22    'NPTS',
23    'LOG_SPACED']
24
25class DataWidgetMapper(QtWidgets.QDataWidgetMapper):
26    """
27    Custom version of the standard QDataWidgetMapper allowing for proper
28    response to index change in comboboxes
29    """
30    def addMapping(self, widget, section, propertyName=None):
31        if propertyName is None:
32            super(DataWidgetMapper, self).addMapping(widget, section)
33        else:
34            super(DataWidgetMapper, self).addMapping(widget, section, propertyName)
35
36        if isinstance(widget, QtWidgets.QComboBox):
37            delegate = self.itemDelegate()
38            widget.currentIndexChanged.connect(lambda: delegate.commitData.emit(widget))
39
40        elif isinstance(widget, QtWidgets.QCheckBox):
41            delegate = self.itemDelegate()
42            widget.stateChanged.connect(lambda: delegate.commitData.emit(widget))
43
44class OptionsWidget(QtWidgets.QWidget, Ui_tabOptions):
45    plot_signal = QtCore.pyqtSignal()
46    def __init__(self, parent=None, logic=None):
47        super(OptionsWidget, self).__init__()
48
49        self.setupUi(self)
50
51        # Logic component
52        self.logic = logic
53        self.parent = parent
54
55        # Weight radio box group
56        self.weightingGroup = QtWidgets.QButtonGroup()
57        self.weighting = 0
58
59        # Group boxes
60        self.boxWeighting.setEnabled(False)
61        self.cmdMaskEdit.setEnabled(False)
62        # Button groups
63        self.weightingGroup.addButton(self.rbWeighting1)
64        self.weightingGroup.addButton(self.rbWeighting2)
65        self.weightingGroup.addButton(self.rbWeighting3)
66        self.weightingGroup.addButton(self.rbWeighting4)
67
68        # Let only floats in the range edits
69        self.txtMinRange.setValidator(GuiUtils.DoubleValidator())
70        self.txtMaxRange.setValidator(GuiUtils.DoubleValidator())
71        # Let only ints in the number of points edit
72        self.txtNpts.setValidator(QtGui.QIntValidator())
73
74        # Attach slots
75        self.cmdReset.clicked.connect(self.onRangeReset)
76        self.cmdMaskEdit.clicked.connect(self.onMaskEdit)
77        self.chkLogData.stateChanged.connect(self.toggleLogData)
78        # Button groups
79        self.weightingGroup.buttonClicked.connect(self.onWeightingChoice)
80
81        self.initModel()
82        self.initMapper()
83        self.model.blockSignals(True)
84        self.updateQRange(QMIN_DEFAULT, QMAX_DEFAULT, NPTS_DEFAULT)
85        self.txtMaxRange.setText(str(QMAX_DEFAULT))
86        self.txtMinRange.setText(str(QMIN_DEFAULT))
87        self.txtNpts.setText(str(NPTS_DEFAULT))
88        self.txtNptsFit.setText(str(NPTS_DEFAULT))
89        self.model.blockSignals(False)
90
91        new_font = 'font-family: -apple-system, "Helvetica Neue", "Ubuntu";'
92        self.label_13.setStyleSheet(new_font)
93        self.label_15.setStyleSheet(new_font)
94
95    def initModel(self):
96        """
97        Initialize the state
98        """
99        self.model = QtGui.QStandardItemModel()
100        for model_item in range(len(MODEL)):
101            self.model.setItem(model_item, QtGui.QStandardItem())
102        # Attach slot
103        self.model.dataChanged.connect(self.onModelChange)
104
105    def initMapper(self):
106        """
107        Initialize model item <-> UI element mapping
108        """
109        self.mapper = DataWidgetMapper(self)
110
111        self.mapper.setModel(self.model)
112        self.mapper.setOrientation(QtCore.Qt.Vertical)
113
114        self.mapper.addMapping(self.txtMinRange, MODEL.index('MIN_RANGE'))
115        self.mapper.addMapping(self.txtMaxRange, MODEL.index('MAX_RANGE'))
116        self.mapper.addMapping(self.txtNpts,     MODEL.index('NPTS'))
117        self.mapper.addMapping(self.chkLogData,  MODEL.index('LOG_SPACED'))
118        # FIXME DOESNT WORK WITH QT5
119        #self.mapper.toFirst()
120
121    def toggleLogData(self, isChecked):
122        """ Toggles between log and linear data sets """
123        pass
124
125    def onMaskEdit(self):
126        """
127        Callback for running the mask editor
128        """
129        pass
130
131    def onRangeReset(self):
132        """
133        Callback for resetting qmin/qmax
134        """
135        self.updateQRange(QMIN_DEFAULT, QMAX_DEFAULT, NPTS_DEFAULT)
136
137    def onWeightingChoice(self, button):
138        """
139        Update weighting in the fit state
140        """
141        button_id = button.group().checkedId()
142        self.weighting = abs(button_id + 2)
143        #self.fitPage.weighting = button_id
144
145    def onModelChange(self, top, bottom):
146        """
147        Respond to model change by updating the plot
148        """
149        # "bottom" is unused
150        # update if there's something to update
151        if str(self.model.item(top.row()).text()):
152            self.plot_signal.emit()
153
154    def setEnablementOnDataLoad(self):
155        """
156        Enable/disable various UI elements based on data loaded
157        """
158        self.boxWeighting.setEnabled(True)
159        self.cmdMaskEdit.setEnabled(True)
160        # Switch off txtNpts related controls
161        self.txtNpts.setEnabled(False)
162        self.txtNptsFit.setEnabled(False)
163        self.chkLogData.setEnabled(False)
164        # Weighting controls
165        if isinstance(self.logic.data, Data2D):
166            if self.logic.data.err_data is None or\
167                    np.all(err == 1 for err in self.logic.data.err_data) or \
168                    not np.any(self.logic.data.err_data):
169                self.rbWeighting2.setEnabled(False)
170                self.rbWeighting1.setChecked(True)
171            else:
172                self.rbWeighting2.setEnabled(True)
173                self.rbWeighting2.setChecked(True)
174        else:
175            if self.logic.data.dy is None or\
176                    np.all(self.logic.data.dy == 1) or\
177                    not np.any(self.logic.data.dy):
178                self.rbWeighting2.setEnabled(False)
179                self.rbWeighting1.setChecked(True)
180            else:
181                self.rbWeighting2.setEnabled(True)
182                self.rbWeighting2.setChecked(True)
183
184    def updateQRange(self, q_range_min, q_range_max, npts):
185        """
186        Update the local model based on calculated values
187        """
188        self.model.item(MODEL.index('MIN_RANGE')).setText(str(q_range_min))
189        self.model.item(MODEL.index('MAX_RANGE')).setText(str(q_range_max))
190        self.model.item(MODEL.index('NPTS')).setText(str(npts))
191
192    def state(self):
193        """
194        Returns current state of controls
195        """
196        q_range_min = float(self.model.item(MODEL.index('MIN_RANGE')).text())
197        q_range_max = float(self.model.item(MODEL.index('MAX_RANGE')).text())
198        npts = int(self.model.item(MODEL.index('NPTS')).text())
199        log_points = str(self.model.item(MODEL.index('LOG_SPACED')).text()) == 'true'
200
201        return (q_range_min, q_range_max, npts, log_points, self.weighting)
Note: See TracBrowser for help on using the repository browser.