Changeset 161713c in sasview


Ignore:
Timestamp:
Feb 14, 2017 9:14:11 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
4c7dd9f
Parents:
7b8485f
Message:

Validate Table View entries in 2D slicer parameter editor - prototype for future use in fitting

Location:
src/sas
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Plotter2D.py

    r7b8485f r161713c  
    136136        self.actionDataInfo = self.contextMenu.addAction("&DataInfo") 
    137137        self.actionDataInfo.triggered.connect( 
    138             functools.partial(self.onDataInfo, self.data)) 
     138             functools.partial(self.onDataInfo, self.data)) 
    139139 
    140140        self.actionSavePointsAsFile = self.contextMenu.addAction("&Save Points as a File") 
    141141        self.actionSavePointsAsFile.triggered.connect( 
    142             functools.partial(self.onSavePoints, self.data)) 
     142             functools.partial(self.onSavePoints, self.data)) 
    143143        self.contextMenu.addSeparator() 
    144144 
     
    225225        self.param_model = self.slicer.model() 
    226226        # Pass the model to the Slicer Parameters widget 
    227         self.slicer_widget = SlicerParameters(model=self.param_model) 
     227        self.slicer_widget = SlicerParameters(model=self.param_model, 
     228                                              validate_method=self.slicer.validate) 
    228229        self.slicer_widget.close_signal.connect(slicer_closed) 
    229230        # Add the plot to the workspace 
  • src/sas/qtgui/SlicerModel.py

    • Property mode changed from 100755 to 100644
    r3bdbfcc r161713c  
    5252        raise NotImplementedError("Parameter setter must be implemented in derived class.") 
    5353 
     54    def validate(self): 
     55        ''' pure virtual ''' 
     56        raise NotImplementedError("Validator must be implemented in derived class.") 
     57 
  • src/sas/qtgui/SlicerParameters.py

    r9a05a8d5 r161713c  
    22Allows users to modify the box slicer parameters. 
    33""" 
     4import numpy 
    45import functools 
    56from PyQt4 import QtGui 
     
    1617    """ 
    1718    close_signal = QtCore.pyqtSignal() 
    18     def __init__(self, model=None): 
     19    def __init__(self, model=None, validate_method=None): 
    1920        super(SlicerParameters, self).__init__() 
    2021 
    2122        self.setupUi(self) 
     23 
    2224        assert isinstance(model, QtGui.QStandardItemModel) 
    2325 
    2426        self.model = model 
     27        self.validate_method = validate_method 
    2528 
    2629        # Define a proxy model so cell enablement can be finegrained. 
     
    3538 
    3639        # Specify the validator on the parameter value column. 
    37         self.lstParams.setItemDelegate(ValidatedItemDelegate()) 
     40        self.delegate = EditDelegate(self, validate_method=self.validate_method) 
     41        self.lstParams.setItemDelegate(self.delegate) 
     42        self.delegate.refocus_signal.connect(self.onFocus) 
    3843 
    3944        # Display Help on clicking the button 
     
    5358        header.setStretchLastSection(True) 
    5459 
     60    def onFocus(self, row, column): 
     61        """ Set the focus on the cell (row, column) """ 
     62        selection_model = self.lstParams.selectionModel() 
     63        selection_model.select(self.model.index(row, column), QtGui.QItemSelectionModel.Select) 
     64        self.lstParams.setSelectionModel(selection_model) 
     65        self.lstParams.setCurrentIndex(self.model.index(row, column)) 
    5566 
    5667    def setModel(self, model): 
     
    105116        return flags 
    106117 
     118class PositiveDoubleEditor(QtGui.QLineEdit): 
     119    # a signal to tell the delegate when we have finished editing 
     120    editingFinished = QtCore.Signal() 
    107121 
    108 class ValidatedItemDelegate(QtGui.QStyledItemDelegate): 
    109     """ 
    110     Simple delegate enabling adding a validator to a cell editor. 
    111     """ 
    112     def createEditor(self, widget, option, index): 
    113         '''Overwrite default editor''' 
    114         if not index.isValid(): 
    115             return 0 
    116         if index.column() == 1: # Edir only cells in the second column 
    117             editor = QtGui.QLineEdit(widget) 
     122    def __init__(self, parent=None): 
     123            # Initialize the editor object 
     124            super(PositiveDoubleEditor, self).__init__(parent) 
     125            self.setAutoFillBackground(True) 
    118126            validator = QtGui.QDoubleValidator() 
    119127            # Don't use the scientific notation, cause 'e'. 
    120128            validator.setNotation(QtGui.QDoubleValidator.StandardNotation) 
    121             editor.setValidator(validator) 
    122             return editor 
    123         return super(ValidatedItemDelegate, self).createEditor(widget, option, index) 
     129 
     130            self.setValidator(validator) 
     131 
     132    def focusOutEvent(self, event): 
     133            # Once focus is lost, tell the delegate we're done editing 
     134            self.editingFinished.emit() 
     135 
     136 
     137class EditDelegate(QtGui.QStyledItemDelegate): 
     138    refocus_signal = QtCore.pyqtSignal(int, int) 
     139    def __init__(self, parent=None, validate_method=None): 
     140        super(EditDelegate, self).__init__(parent) 
     141        self.editor = None 
     142        self.index = None 
     143        self.validate_method = validate_method 
     144 
     145    def createEditor(self, parent, option, index): 
     146        # Creates and returns the custom editor object we will use to edit the cell 
     147        if not index.isValid(): 
     148            return 0 
     149 
     150        result = index.column() 
     151        if result==1: 
     152                self.editor = PositiveDoubleEditor(parent) 
     153                self.index = index 
     154                return self.editor 
     155        else: 
     156                return QtGui.QStyledItemDelegate.createEditor(self, parent, option, index) 
     157 
     158    def setModelData(self, editor, model, index): 
     159        """ 
     160        Custom version of the model update, rejecting bad values 
     161        """ 
     162        self.index = index 
     163 
     164        # Find out the changed parameter name and proposed value 
     165        new_value = self.editor.text().toFloat()[0] 
     166        param_name = str(model.sourceModel().item(index.row(),0).text()) 
     167 
     168        validated = True 
     169        if self.validate_method: 
     170            # Validate the proposed value in the slicer 
     171            value_accepted = self.validate_method(param_name, new_value) 
     172 
     173        if value_accepted: 
     174            # Update the model only if value accepted 
     175            return super(EditDelegate, self).setModelData(editor, model, index)           
  • src/sas/sasgui/guiframe/local_perspectives/plotting/AnnulusSlicer.py

    r3bdbfcc r161713c  
    154154        self.draw() 
    155155 
     156    def validate(self, param_name, param_value): 
     157        """ 
     158        Test the proposed new value "value" for row "row" of parameters 
     159        """ 
     160        MIN_DIFFERENCE = 0.01 
     161        isValid = True 
     162 
     163        if param_name == 'inner_radius': 
     164            # First, check the closeness 
     165            if numpy.fabs(param_value - self.getParams()['outer_radius']) < MIN_DIFFERENCE: 
     166                print("Inner and outer radii too close. Please adjust.") 
     167                isValid = False 
     168            elif param_value > self.qmax: 
     169                print("Inner radius exceeds maximum range. Please adjust.") 
     170                isValid = False 
     171        elif param_name == 'outer_radius': 
     172            # First, check the closeness 
     173            if numpy.fabs(param_value - self.getParams()['inner_radius']) < MIN_DIFFERENCE: 
     174                print("Inner and outer radii too close. Please adjust.") 
     175                isValid = False 
     176            elif param_value > self.qmax: 
     177                print("Outer radius exceeds maximum range. Please adjust.") 
     178                isValid = False 
     179        elif param_name == 'nbins': 
     180            # Can't be 0 
     181            if param_value < 1: 
     182                print("Number of bins cannot be less than or equal to 0. Please adjust.") 
     183                isValid = False 
     184 
     185        return isValid 
    156186 
    157187    def moveend(self, ev): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/AzimutSlicer.py

    rd85c194 r161713c  
    182182                     NewPlotEvent(plot=new_plot, title=str(new_sector.__name__))) 
    183183 
     184 
     185    def validate(self, param_name, param_value): 
     186        """ 
     187        Test the proposed new value "value" for row "row" of parameters 
     188        """ 
     189        # Here, always return true 
     190        return True 
     191 
    184192    def moveend(self, ev): 
    185193        #TODO: why is this empty? 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/SectorSlicer.py

    r57b7ee2 r161713c  
    176176        self.draw() 
    177177 
     178    def validate(self, param_name, param_value): 
     179        """ 
     180        Test the proposed new value "value" for row "row" of parameters 
     181        """ 
     182        MIN_DIFFERENCE = 0.01 
     183        isValid = True 
     184 
     185        if param_name == 'Delta_Phi [deg]': 
     186            # First, check the closeness 
     187            if numpy.fabs(param_value) < MIN_DIFFERENCE: 
     188                print("Sector angles too close. Please adjust.") 
     189                isValid = False 
     190        elif param_name == 'nbins': 
     191            # Can't be 0 
     192            if param_value < 1: 
     193                print("Number of bins cannot be less than or equal to 0. Please adjust.") 
     194                isValid = False 
     195        return isValid 
     196 
    178197    def moveend(self, ev): 
    179198        """ 
Note: See TracChangeset for help on using the changeset viewer.