Select to view content in your preferred language

A toolbox parameter can either depend on other parameters or user enter value, how to realize?

663
4
10-19-2023 02:48 PM
WeiMao
by
Emerging Contributor

I'm a newbie and I am creating a toolbox for python. I have a parameter A about categories that need to be selected by the user, there are 5 categories. Parameter A selects a category, and parameter B and C show the default parameter when that category is selected. If the user has a measured value for parameter B or C, then they can also enter it themselves.

I have created the following code but it is not working properly. When I change the value of A, B and C do not change with it. What should I do, please?

 

 

import arcpy

default = {"Class A":  [1.46, 1.50],
           "Class B":  [1.46, 1.70],
           "Class C":  [0.35, 1.50],
           "Class D":  [0.35, 1.80],
           "Class E":  [0.35, 1.50]}
   
class Interfacemodel(object):
    def __init__(self) -> None:
    self.label = "model"
        self.description = """model"""

def getParameterInfo(self) -> list:
        """Define parameter definitions.
        """
        Option = arcpy.Parameter(name="class",
                                 displayName="class",
                                 datatype="String",
                                 parameterType="Required",
                                 direction="Input")
        choices = ["Class A", "Class B", "Class C", "Class D", "Class E"]
        Option.filter.list = choices
        Option.value = "Class A"

    param0 = arcpy.Parameter(name="param0",
                                 displayName="param0",
                                 datatype="GPDouble",
                                 parameterType="Required",
                                 direction="Input")
        param0.value = 1.46

param1 = arcpy.Parameter(name="param1",
                                 displayName="param1",
                                 datatype="GPDouble",
                                 parameterType="Required",
                                 direction="Input")
        param0.value = 1.50

return [Option, param0, param1]

def updateParameters(self, parameters) -> None:
    if parameters[0].altered:
            if not parameters[1].altered:
                parameters[1].value = default[parameters[0].valueAsText][0]
            if not parameters[2].altered:
                parameters[2].value = default[parameters[0].valueAsText][1]

 

 

0 Kudos
4 Replies
BlakeTerhune
MVP Regular Contributor

Reading the documentation, it says:

Once a parameter has been altered, it remains altered until the user empties (removes) the value in which case it returns to an unaltered state. Programmatically changing a value with validation code will change the altered state. That is, if you set a value for a parameter, the altered state of the parameter will be updated.

So when you set the value of the parameter in getParameterInfo(), I think it's coming through as altered in updateParameters(). Try removing the lines where you set the value of param0 and param1. You can also use the hasBeenValidated property to determine if it was changed.

Maybe to simplify this, try checking if there is a value and, if not, set the default.

if parameters[0].value:
    if not parameters[1].value:
        parameters[1].value = default[parameters[0].valueAsText][0]
    if not parameters[2].value:
        parameters[2].value = default[parameters[0].valueAsText][1]
else:
    parameters[1].value = None
    parameters[2].value = None
0 Kudos
WeiMao
by
Emerging Contributor

Thank you very much sir. I tried the above code, but with a little regret. For example, when I select Class C, the value of parameters[1] doesn't change automatically, it only changes to the default value when I remove its value.

 The intention is that when I choose different class, the parameters will automatically change to the default value. But users are allowed to change the default value if they want to. I'm still trying and haven't found a better solution yet.

0 Kudos
BlakeTerhune
MVP Regular Contributor

Okay, maybe something like this then.

if parameters[0].value:
    if not parameters[0].hasBeenValidated:
        param0_default, param1_default = default[parameters[0].valueAsText]
        parameters[1].value = param0_default
        parameters[2].value = param1_default
else:
    parameters[1].value = None
    parameters[2].value = None

Using the hasBeenValidated property will tell you if it was just changed. So with this, if the category was just changed, set the default measured values. After that, if the user changes the default measured values, they should be left alone. The measured values would only get changed if the user changed the category again.

0 Kudos
WeiMao
by
Emerging Contributor

Great. Thank you very much, sir.

0 Kudos