+ Reply to Thread
Results 1 to 2 of 2

Thread: Listbox patterns or how do you string dependent inpu parameters in updateParametes()?

  1. #1
    brad eckrose
    Join Date
    Jul 2010
    Posts
    30
    Points
    1
    Answers Provided
    0


    0

    Default Listbox patterns or how do you string dependent inpu parameters in updateParametes()?

    GPers,

    Having given up on ModelBuilder and Script Tools due to repeated Arc Desktop crashes, I have arrived down at the bare-metal: the promising Python Toolbox.

    I'm trying to write a tool that allows the user choose the workspace, then select from a specific set of feature classes, then automatically fill a dropdown of filtered subtypes for the selected feature.

    This immediately presents the following problems:
    What datatype to set for the parameters? Should I make them all string instead of Workspace, feature class, etc
    Is there an enumeration for the arcpy parameter datatypes so I don't have to type the bloody things and spell them correctly?
    How to detect the appropriate change-events?
    Should I set parameterDependencies() for any of them?
    What is the actual datatype of arcpy.Parameter.value? a describe object? a string? type (arcpy.Parameter.value) merely returns "property"
    Is there an arcpy.mapping dialog box that can display a table control?
    For coded picklists, like subtypes, what is the strategy for picking the value, yet returning the code so it can be used in a SQL expression? The best I've seen is a list expansion with a value matching criteria. Can this be handled if the argument were defined as a Field Info instead?

    Thus far, this is all I've been able to muster with no success:

    Code:
    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 = [FeaturesBySubtype]
    
    
    class AbstractTool(object):
        def __init__(self):
            """Define the tool (tool name is the name of the class)."""
            self.label = "Tool"
            self.description = ""
            self.canRunInBackground = False
    
        def getParameterInfo(self):
            """Define parameter definitions"""
            params = None
            return params
    
        def isLicensed(self):
            """Set whether tool is licensed to execute."""
            return True
    
        def updateParameters(self, parameters):
            """Modify the values and properties of parameters before internal
            validation is performed.  This method is called whenever a parameter
            has been changed."""
            return
    
        def updateMessages(self, parameters):
            """Modify the messages created by internal validation for each tool
            parameter.  This method is called after internal validation."""
            return
    
        def execute(self, parameters, messages):
            """The source code of the tool."""
            return
    
    class FeaturesBySubtype(AbstractTool):
        def __init__(self):
            self.label = "Query Features By Subtype"
            self.description = "Return all the features of the specified subtype for the specified feature class"
            self.canRunInBackground = True
    
        def getParameterInfo(self):
            p1 = arcpy.Parameter(
                displayName="Workspace",
                name="in_workspace",
                datatype="Workspace",
                parameterType="Required",
                direction="Input")
    
            p2 = arcpy.Parameter(
                displayName="Feature Class",
                name="in_featureclass",
                datatype="Feature Class",
                parameterType="Required",
                direction="Input")
    
            p3 = arcpy.Parameter(
                displayName="Subtype",
                name="in_subtype",
                datatype="string",
                parameterType="Required",
                direction="Input")
    
            p4 = arcpy.Parameter(
                displayName="Output Table",
                name="out_resulttable",
                datatype="Table View",
                parameterType="Required",
                direction="Output")
            
            params = [p1,p2,p3,p4]
            return params
        
    
        def updateParameters(self, parameters):
            if parameters[0].value:
                arcpy.env.workspace=parameters[0].value
                
            for a_parm in parameters:
                if a_parm.altered and not(a_parm.hasBeenValidated):
                   a_parm.setWarningMessage(str.format('Parameter modified {0}', a_parm.name)  )
            parameters[1].filter.list=['Fuse','Switch']
            st = arcpy.da.ListSubtypes('Fuse')
            parameters[2].filter.type='ValueList'
            parameters[2].filter.list = st.values()
            return
        
        
        def execute(self, parameters, messages):
            arcpy.AddMessage(parameters)
            
            tableList = [parameters[1].value]
            
            fc_descr = arcpy.Describe ( parameters[1].value)
            subtype_field = fc_descr.subtypeFieldName
            
            whereClause = str.format("{0}={1}",subtype_field,parameters[2].value)
            lyrName = "QueryOutput"
            
            arcpy.AddMessage(whereClause)
            # Make Query Table...
            arcpy.MakeQueryTable_management(tableList, lyrName, None, None, None, whereClause)
         
            # Print the total rows
            arcpy.AddMessage( arcpy.GetCount_management(lyrName))
         
    
            return

  2. #2
    Curtis Price

    Join Date
    Oct 2009
    Posts
    1,798
    Points
    874
    Answers Provided
    127


    0

    Default Re: How do you string dependent input parameters in updateParameters?

    Quote Originally Posted by blekros View Post
    Having given up on ModelBuilder and Script Tools due to repeated Arc Desktop crashes, I have arrived down at the bare-metal: the promising Python Toolbox.
    Hate to tell you Brad, but I've found .pyt to be pretty unstable compared to script toolboxes until you have enough experience to get the syntax exactly right. Also, if you were doing things with script tool validation etc that was crashing ArcMap, the same validation code will crash ArcMap just as effectively. As far as I can tell, the tbx is simply a slightly different implementation of the same framework used in the pyt file. You do have a little more control with value table parameters than the tbx property sheets support. (Maybe an Esri person can chime in, as I haven't gotten into that yet.)

    What datatype to set for the parameters? Should I make them all string instead of Workspace, feature class, etc
    Is there an enumeration for the arcpy parameter datatypes so I don't have to type the bloody things and spell them correctly?
    How to detect the appropriate change-events?
    This is the same as it is with the validation code for tbx script tools. For datatypes that have string representation like Field, you can generate picklists as strings and then apply them to a filter. ".value" is the arcpy data type you have set it to be (that may or may not have an easy string representation you can use. Depends on the data type).
    Arc 10.1 Help:
    Understanding validation in script tools
    Customizing tool behavior in a Python toolbox

    So far I haven't been convinced to abandon the .tbx format in my work because 1) the tbx can store tool documentation inside the file and a .pyt doc hangs out in parallel .xml files, 2) I have 10.0 users to support, and 3) I am one of those lazy people that likes it when someone does my work for me with property sheet interfaces so I don't have to write the code myself. (OK, I'll come clean, the folks that implemented the tbx properties are far better Python programmers than me.)

    Honestly if you're getting started with Python toolboxes, I feel the best approach to start with is to make a good old fashioned tbx script tool with validation set up for you from the script tool's property sheets (and maybe a little of your own in the Validation tab), then convert to a pyt using this conversion tool.

    Once you've done this you'll have auto-generated code to start with so you can get familiar with how it works with your particular application.
    Last edited by curtvprice; 02-28-2013 at 09:16 AM.

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts