Python Toolbox - Only update parameter when specific parameter changes
The "arcpy way ™" is to check if parameters[0].altered and not parameters[0].hasBeenValidated:
According to the documentation:
altered
altered
is true if the value of a parameter is changed... Once a parameter has been altered, it remains altered until the user empties (blanks out) the value, in which case it returns to being unaltered.hasBeenValidated
hasBeenValidated
is false if a parameter's value has been modified by the user since the last timeupdateParameters
and internal validate were called. Once internal validate has been called, geoprocessing automatically setshasBeenValidated
to true for every parameter.
hasBeenValidated
is used to determine whether the user has changed a value since the last call toupdateParameters
.
For example, a simplified version of your code (doesn't disable/enable, just empties/populates parameters[2]
):
import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
self.label = "Tool"
self.description = "A Tool"
self.canRunInBackground = False
def getParameterInfo(self):
inGdb = arcpy.Parameter(
displayName = "Input Geodatabase",
name = "ingdb",
datatype = "DEWorkspace",
parameterType = "Required",
direction = "Input")
# Set the filter to accept only local geodatabases
inGdb.filter.list = ["Local Database"]
outGdb = arcpy.Parameter(
displayName = "Output Geodatabase",
name = "outgdb",
datatype = "DEWorkspace",
parameterType = "Required",
direction = "Input")
# Set the filter to accept only local geodatabases
outGdb.filter.list = ["Local Database"]
inFcs = arcpy.Parameter(
displayName = "Feature Classes And Tables",
name = "infcs",
datatype = "GPString",
parameterType = "Required",
direction = "Input",
multiValue = True)
return [inGdb, outGdb, inFcs]
def updateParameters(self, parameters):
if not parameters[0].altered:
parameters[2].filter.list = []
parameters[2].value = None
elif parameters[0].altered and not parameters[0].hasBeenValidated:
gdb = parameters[0].valueAsText
arcpy.env.workspace = gdb
fcs = []
for typ in ["Point", "Polygon", "Polyline", "Multipoint"]:
fcs += ["{} (Feature Class)".format(fc) for fc in arcpy.ListFeatureClasses(feature_type = typ)]
fcs += ["{} (Table)".format(tab) for tab in arcpy.ListTables()]
datasets = arcpy.ListDatasets()
for dataset in datasets:
for typ in ["Point", "Polygon", "Polyline", "Multipoint"]:
dsFcs = arcpy.ListFeatureClasses(None, typ, dataset)
for dsFc in dsFcs:
fc = os.path.join(dataset, dsFc)
fcs += [fc]
parameters[2].filter.list = fcs
For this one a use of a global variable will help:
currentValue = '' # to avoid problems later give it an empty string
def updateParameters(self, parameters):
global currentValue
if parameters[0].valueAsText != currentValue:
currentValue = parameters[0].valueAsText
# the rest of your code
Python is a bit finicky about that sort of thing, if you don't tell it you want to use the existing global variable it will assume that it's a new local variable (which has a value of None).
Global variables are handy and have a purpose but I would warn future readers of this post to not over-use global variables.. I have read some articles that suggest that globals in python chew up memory needlessly.