source: sasview/src/sas/qtgui/Perspectives/Fitting/SmearingWidget.py @ fbfc488

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 fbfc488 was 4992ff2, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Initial, in-progress version. Not really working atm. SASVIEW-787

  • Property mode set to 100644
File size: 6.5 KB
Line 
1"""
2Widget/logic for smearing data.
3"""
4from PyQt5 import QtCore
5from PyQt5 import QtGui
6from PyQt5 import QtWidgets
7
8from sas.qtgui.Plotting.PlotterData import Data1D
9from sas.qtgui.Plotting.PlotterData import Data2D
10
11# Local UI
12from sas.qtgui.Perspectives.Fitting.UI.SmearingWidgetUI import Ui_SmearingWidgetUI
13
14class DataWidgetMapper(QtWidgets.QDataWidgetMapper):
15    """
16    Custom version of the standard QDataWidgetMapper allowing for proper
17    response to index change in comboboxes
18    """
19    def addMapping(self, widget, section, propertyName=None):
20        if propertyName is None:
21            super(DataWidgetMapper, self).addMapping(widget, section)
22        else:
23            super(DataWidgetMapper, self).addMapping(widget, section, propertyName)
24
25        if isinstance(widget, QtWidgets.QComboBox):
26            delegate = self.itemDelegate()
27            widget.currentIndexChanged.connect(lambda: delegate.commitData.emit(widget))
28
29SMEARING_1D = ["Custom Pinhole Smear", "Custom Slit Smear"]
30SMEARING_2D = ["Custom Pinhole Smear"]
31
32MODEL = [
33    'SMEARING',
34    'PINHOLE_MIN',
35    'PINHOLE_MAX',
36    'ACCURACY']
37
38class SmearingWidget(QtWidgets.QWidget, Ui_SmearingWidgetUI):
39    def __init__(self, parent=None):
40        super(SmearingWidget, self).__init__()
41
42        self.setupUi(self)
43
44        # Have we loaded data yet? If so, what kind
45        self.have_data = None
46        # Local model for holding data
47        self.model = None
48        # Mapper for model update
49        self.mapper = None
50
51        self.parent = parent
52        # Let only floats in the line edits
53        self.txtSmearDown.setValidator(QtGui.QDoubleValidator())
54        self.txtSmearUp.setValidator(QtGui.QDoubleValidator())
55
56        # Attach slots
57        self.cbSmearing.currentIndexChanged.connect(self.onIndexChange)
58        self.cbSmearing.setCurrentIndex(0)
59
60        self.initModel()
61        self.initMapper()
62
63    def initModel(self):
64        """
65        Initialize the state
66        """
67        self.model = QtGui.QStandardItemModel()
68        for model_item in range(len(MODEL)):
69            self.model.setItem(model_item, QtGui.QStandardItem())
70        # Attach slot
71        self.model.dataChanged.connect(self.onModelChange)
72
73    def initMapper(self):
74        """
75        Initialize model item <-> UI element mapping
76        """
77        self.mapper = DataWidgetMapper(self)
78
79        self.mapper.setModel(self.model)
80        self.mapper.setOrientation(QtCore.Qt.Vertical)
81
82        self.mapper.addMapping(self.txtSmearUp,   MODEL.index('PINHOLE_MIN'))
83        self.mapper.addMapping(self.txtSmearDown, MODEL.index('PINHOLE_MAX'))
84        self.mapper.addMapping(self.cbSmearing,   MODEL.index('SMEARING'))
85        self.mapper.addMapping(self.cbAccuracy,   MODEL.index('ACCURACY'))
86
87        # FIXME DOESNT WORK WITH QT5
88        #self.mapper.toFirst()
89
90    def updateSmearing(self, data=None):
91        """
92        Update control elements based on data passed
93        """
94        self.cbSmearing.clear()
95        self.cbSmearing.addItem("None")
96        self.cbAccuracy.setVisible(False)
97
98        if data is None:
99            self.setElementsVisibility(False)
100        elif isinstance(data, Data1D):
101            self.cbSmearing.addItems(SMEARING_1D)
102            self.have_data = Data1D
103        else:
104            self.cbSmearing.addItems(SMEARING_2D)
105            self.have_data = Data2D
106        self.cbSmearing.setCurrentIndex(0)
107
108    def onIndexChange(self, index):
109        """
110        Callback for smearing combobox index change
111        """
112        if index == 0:
113            self.setElementsVisibility(False)
114            return
115        elif index == 1:
116            self.setElementsVisibility(True)
117            self.setPinholeLabels()
118        elif index == 2:
119            self.setElementsVisibility(True)
120            self.setSlitLabels()
121
122    def onModelChange(self, top, bottom):
123        """
124        Respond to model change by updating
125        """
126        #print "MODEL CHANGED for property: %s. The value is now: %s" % \
127        #    (MODEL[top.row()], str(self.model.item(top.row()).text()))
128        pass
129
130    def setElementsVisibility(self, visible):
131        """
132        Labels and linedits visibility control
133        """
134        self.lblSmearDown.setVisible(visible)
135        self.lblSmearUp.setVisible(visible)
136        self.txtSmearDown.setVisible(visible)
137        self.txtSmearUp.setVisible(visible)
138        self.label_14.setVisible(visible)
139        self.label_15.setVisible(visible)
140        self.setAccuracyVisibility()
141
142    def setAccuracyVisibility(self):
143        """
144        Accuracy combobox visibility
145        """
146        if self.have_data == Data2D and self.cbSmearing.currentIndex() == 1:
147            self.cbAccuracy.setVisible(True)
148        else:
149            self.cbAccuracy.setVisible(False)
150
151    def setPinholeLabels(self):
152        """
153        Use pinhole labels
154        """
155        self.lblSmearUp.setText('<html><head/><body><p>dQ<span style=" vertical-align:sub;">low</span></p></body></html>')
156        self.lblSmearDown.setText('<html><head/><body><p>dQ<span style=" vertical-align:sub;">high</span></p></body></html>')
157
158    def setSlitLabels(self):
159        """
160        Use pinhole labels
161        """
162        self.lblSmearUp.setText('Slit height')
163        self.lblSmearDown.setText('Slit width')
164
165    def state(self):
166        """
167        Returns current state of controls
168        """
169        # or model-held values
170        smearing = str(self.model.item(MODEL.index('SMEARING')).text())
171        accuracy = ""
172        d_down = None
173        d_up = None
174        if smearing != "None":
175            accuracy = str(self.model.item(MODEL.index('ACCURACY')).text())
176            try:
177                d_down = float(self.model.item(MODEL.index('PINHOLE_MIN')).text())
178            except ValueError:
179                d_down = None
180            try:
181                d_up = float(self.model.item(MODEL.index('PINHOLE_MAX')).text())
182            except ValueError:
183                d_up = None
184
185        return (smearing, accuracy, d_down, d_up)
186
187    def setState(self, smearing, accuracy, d_down, d_up):
188        """
189        Sets new values for the controls
190        """
191        # Update the model -> controls update automatically
192        if smearing is not None:
193            self.model.item(MODEL.index('SMEARING')).setText(smearing)
194        if accuracy is not None:
195            self.model.item(MODEL.index('ACCURACY')).setText(accuracy)
196        if d_down is not None:
197            self.model.item(MODEL.index('PINHOLE_MIN')).setText(d_down)
198        if d_up is not None:
199            self.model.item(MODEL.index('PINHOLE_MAX')).setText(d_up)
200
Note: See TracBrowser for help on using the repository browser.