I am trying to script some behavior into the ArcGIS Toolbox validator class. Specifically, I am creating a dropdown parameter so the user can choose a predefined option and then a second parameter will update a list of items. The issue I am having is, when I change the option in the first parameter, I can get the options to change in the second parameter, but when I toggle the 'Unselect All' button in the second parameter, the items will not uncheck (they remained checked). I have a feeling it has to do with my script in the Validator.
Here are the details (see image below as well):
So, in the Validator, my script is as follows. Can anyone see something obvious I ma misisng here to get the 'Select All' and 'Unselect All' buttons to work?
import arcpy class ToolValidator(object): """Class for validating a tool's parameter values and controlling the behavior of the tool's dialog.""" def __init__(self): """Setup arcpy and the list of tool parameters.""" self.params = arcpy.GetParameterInfo() def initializeParameters(self): """Refine the properties of a tool's parameters. This method is called when the tool is opened.""" self.params[1].filter.list = [1,2,3,4] self.params[1].values = self.params[1].filter.list return def updateParameters(self): """Modify the values and properties of parameters before internal validation is performed. This method is called whenever a parameter has been changed.""" if self.params[0].altered == True: if self.params[0].value == 'Option 1': self.params[1].filter.list = [1,2,3,4] self.params[1].values = self.params[1].filter.list elif self.params[0].value == 'Option 2': self.params[1].filter.list = ['a', 'b', 'c'] self.params[1].values = self.params[1].filter.list elif self.params[0].value == 'Option 3': self.params[1].filter.list = ['dr', 'bht', 'cjjjyy'] self.params[1].values = self.params[1].filter.list return def updateMessages(self): """Modify the messages created by internal validation for each tool parameter. This method is called after internal validation.""" return
I avoid using the "altered" property. Once a parameter has been changed, altered always checks true. In addition, the script tool seems to create new instances of the tool validator every time a parameter is checked. So I check the values of the parameters and take the appropriate actions. Here is my suggestion for your validator code:
import arcpy
class ToolValidator(object):
"""Class for validating a tool's parameter values and controlling
the behavior of the tool's dialog."""
def __init__(self):
"""Setup arcpy and the list of tool parameters."""
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
"""Refine the properties of a tool's parameters. This method is
called when the tool is opened."""
return
def updateParameters(self):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
options = ['Option 1', 'Option 2', 'Option 3']
filters = [['1','2','3','4'], ['a', 'b', 'c'], ['dr', 'bht', 'cjjjyy']]
if self.params[0].value == options[2]:
if self.params[1].filter.list != filters[2]:
self.params[1].filter.list = filters[2] # update filter.list
self.params[1].values = filters[2] # select all
# self.params[1].values = None # clear all selections
elif self.params[0].value == options[1]:
if self.params[1].filter.list != filters[1]:
self.params[1].filter.list = filters[1] # update filter.list
self.params[1].values = filters[1] # select all
# self.params[1].values = None # clear all selections
else:
self.params[0].value = options[0] # set to default value
if self.params[1].filter.list != filters[0]:
self.params[1].filter.list = filters[0] # update filter.list
self.params[1].values = filters[0] # select all
# self.params[1].values = None # clear all selections
return
def updateMessages(self):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
EDIT: I updated my code above after discovering that a user could edit the text for "Option 1", etc., and enter an "Option 4". The code now will set "Option 1" as the default.
In your code, you were changing the filter list and selecting all values to match the "Option n" setting even if the list in use already matched the option. That was causing select/unselect buttons to freeze.
As an alternative to using the "altered" property, you may wish to use the "hasBeenValidated" property. When a parameter has been checked by updateParameters, this value is set to true. When the user changes the parameter, the value is set to false. A code example:
if self.params[0].value and not self.params[0].hasBeenValidated:
Hope this helps.