Subset Selection in Python Add-in tool

1862
7
Jump to solution
01-31-2013 10:36 AM
NoahHuntington
Occasional Contributor
Can anybody tell me why the second combo box (subset selection) does not become enabled in python add-in?
Here is a picture and code...

[ATTACH=CONFIG]21258[/ATTACH]

import arcpy import pythonaddins #Clear any Selections there may be on the Document before it is opened #set the layer variable to the first layer in the map document(coded inline with layer) layer = arcpy.mapping.ListLayers(arcpy.mapping.MapDocument("CURRENT"))[0] # Select the layer to clear any Current selection on the map arcpy.SelectLayerByAttribute_management(layer,"CLEAR_SELECTION") #refresh the active view of the map document arcpy.RefreshActiveView()   class Survey(object):     """Implementation for MapperTest_addin.combobox1 (ComboBox)"""     def __init__(self):         #in the initialisation of the addin         self.items = []         self.editable = True         self.enabled = True         self.dropdownWidth = 'WWWWWW'         self.width = 'WWWWWW'         #set the map document reference         mxd = arcpy.mapping.MapDocument("CURRENT")         #set the dataframe reference using the map document and the first data frame in the list         df = arcpy.mapping.ListDataFrames(mxd)[0]         #set the layer reference using the map document reference and the first layer in the list of layers         layer = arcpy.mapping.ListLayers(mxd)[0]         # check if the layer exists         if layer:             #create a column name variable for the search cursor parameters             column_Survey = "L1SURNAM"             #create a search cursor for the survey name field             sc = arcpy.SearchCursor(layer,""""L1SURNAM" <> ' '""","",column_Survey,column_Survey)             #Due to the multiple values stored in the attribute table a dictionary had to be used             #Create a dictionary             dictionary = {}             #for loop to iterate through the attribute tables getting the values for the column             for row in sc:                 #set the value as the row value in the column Survey                 val = row.getValue(column_Survey)                 #the nature of dictionaries does not allow for duplicates thus handling the redundant block numbers in the data table for use in the combobox                 dictionary[val] = val                 #create a list of items for the dictionary's unique keys to be written to             Items = []             #for loop to iterate through the keys in the dictionary             for key in dictionary.iterkeys():                 #append the key values to the list Items                 Items.append(key)                 #append the list of keys to the Survey(self) item list                 self.items.append(key)             #sort keys in ascending numeric order             self.items.sort()         #delete row variable         del row         #delete search cursor         del sc      def onSelChange(self, selection):         #set the map document reference         mxd = arcpy.mapping.MapDocument("CURRENT")         #set the dataframe reference using the map document and the first data frame in the list         df = arcpy.mapping.ListDataFrames(mxd)[0]         #set the layer reference using the map document reference and the first layer in the list of layers         layer = arcpy.mapping.ListLayers(mxd)[0]         #Use the select by attributed tool to create a new selection of the survey based on the selection in the combobox         arcpy.SelectLayerByAttribute_management(layer,"NEW_SELECTION","L1SURNAM = '" + selection + "'")         #zoom to the selected features in the dataframe         df.zoomToSelectedFeatures()         #refresh the active view         arcpy.RefreshActiveView()         #if the layer exists         if layer:             #empty the block number item list             Block.items = []             #create a variable for the block number             column_Block = "L2BLOCK"             #create a search cursor for the layer on the lot number field selecting all the values that are not an empty string             sc = arcpy.SearchCursor(layer,""""L2BLOCK" <> ' '""","",column_Block,column_Block)             #for loop to read through the values in the block number field             for row in sc:                 #append the lot number items to the block number item list                 LotNumber.items.append(row.getValue(column_Block))                 #once a selection is made the block number box becomes active                 Block.enabled = True         #delete row variable         del row         #delete rsearch cursor         del sc     def onEditChange(self, text):         #create a variable to store the text in for the selection tool         surNam = text         #set the map document reference         mxd = arcpy.mapping.MapDocument("CURRENT")         #set the dataframe reference using the map document and the first data frame in the list         df = arcpy.mapping.ListDataFrames(mxd)[0]         #set the layer reference using the map document reference and the first layer in the list of layers         layer = arcpy.mapping.ListLayers(mxd)[0]         #Selection tool used to select the values in the layer where the survey name is the value that is typed into the combo box         arcpy.SelectLayerByAttribute_management(layer,"NEW_SELECTION","L1SURNAM = '" + surNam + "'")         #Zoom to the selected features         df.zoomToSelectedFeatures()      def onFocus(self, focused):         pass     def onEnter(self):         pass     def refresh(self):         pass   class Block(object):     """Implementation for MapperTest_addin.combobox2 (ComboBox)"""     def __init__(self):         self.items = []         self.editable = True         #only activated when block number is populated         self.enabled = False         self.dropdownWidth = 'WWWWWW'         self.width = 'WWWWWW'     def onSelChange(self, selection):         blockNum = selection         #set the map document reference         mxd = arcpy.mapping.MapDocument("CURRENT")         #set the dataframe reference using the map document and the first data frame in the list         df = arcpy.mapping.ListDataFrames(mxd)[0]         #set the layer reference using the map document reference and the first layer in the list of layers         layer = arcpy.mapping.ListLayers(mxd)[0]         #select a subset from the selected fields of blocknumber         arcpy.SelectLayerByAttribute_management(layer,"SUBSET_SELECTION","L2BLOCK = '" + blockNum + "'")         df.zoomToSelectedFeatures()         arcpy.RefreshActiveView()     def onEditChange(self, text):         pass     def onFocus(self, focused):         pass     def onEnter(self):         pass     def refresh(self):         pass
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ChrisFox3
Occasional Contributor III
Check out the following help topic:

http://resources.arcgis.com/en/help/main/10.1/#/Managing_the_state_of_Python_add_in_types/014p000000...

If you want modify the state of another add-in item you need to reference the ID of the item. In your code you are using the name of the class, Block. Based on the comments in your code the ID of the second combo box is combobox2, so you would need to use that. The ID is defined when you author the addin and is stored in the config.xml.

comboxbox2.enabled = True

View solution in original post

0 Kudos
7 Replies
ChrisFox3
Occasional Contributor III
Check out the following help topic:

http://resources.arcgis.com/en/help/main/10.1/#/Managing_the_state_of_Python_add_in_types/014p000000...

If you want modify the state of another add-in item you need to reference the ID of the item. In your code you are using the name of the class, Block. Based on the comments in your code the ID of the second combo box is combobox2, so you would need to use that. The ID is defined when you author the addin and is stored in the config.xml.

comboxbox2.enabled = True
0 Kudos
NoahHuntington
Occasional Contributor
Thanks!!! I am elaborating on a bit of code shared with me.  Now I can see more clearly what is in the logic.
0 Kudos
NoahHuntington
Occasional Contributor
Chris, If I can pick your mind a bit more.  I was successful in enabling  combobox2 after selection.  How do I populate it with only
unique values?
0 Kudos
ChrisFox3
Occasional Contributor III
If you convert a list to a set it will return only unique values:

>>> list = [1,1,5,5,3,8,9]
>>> set(list)
set([8, 1, 3, 5, 9])
>>>
0 Kudos
NoahHuntington
Occasional Contributor
If you convert a list to a set it will return only unique values:

>>> list = [1,1,5,5,3,8,9]
>>> set(list)
set([8, 1, 3, 5, 9])
>>>

  Thanks Chris! How do I go about populating a combobox from a set when I currently have:
for row in sc:
                #append the lot number items to the lot number item list
                combobox2.items.append(row.getValue(column_Lot)
                #once a selection is made the lot number box becomes active
                combobox2.enabled = True
0 Kudos
ChrisFox3
Occasional Contributor III
I would just create list variable, append to it in the loop, after the loop completes create a set from the list and then assign it to the items property of the combo box.

myList = []
for row in sc:
   myList.append(row.getValue(column_Lot)
mySet = set(myList)
combobox2.items = list(mySet)
combobox2.enabled = True
0 Kudos
PaulScipione1
New Contributor III
This looks exactly like what I've been searching for.  I have been out of Python & ESRI for about 3 years and just now getting back into it.  I currently have several Query Feature Classes, which from the SQL Server end is just a spatial view.  I built a Python add-in for a toolbar, and I have buttons on it.  I want to have code that does the following when selecting one of the buttons:

1. Open a form with 2 pick lists.  The first pick list is populated upon opening with a sorted list of values from the Route field, the 2nd pick list is empty.

2. When a user selects a item from the Route pick list, the 2nd pick list gets populated with a sorted list of Manhole numbers that have the Route value that was selected in the 1st pick list.

3. Upon picking the Manhole number, the form closes and the screen zooms in closely to the feature.  Now, after reading this post, I am wondering if rather than opening a form, if the toolbar should just have the 2 Comboboxes in it, like in the picture example. Probably would save the fuss of forms opening and closing?

At a future date these Query Feature Classes maybe become GDB feature classes and I will need to ensure the code works for that too, so I dont know if the code needs to be slightly different to analyze the layer for the type it is (Query Feature Class or GDB Feature Class).  Is it possible that you can post your final script for your toolbar so that I can try to analyze and tweak it to fit my needs?  I will have other buttons on this toolbar that will do similar search, using unique sorted Route lists to populate sorted lists of Handholes, Poles, Pedestals, etc.  I will also have buttons to do searches that only require one pick list, like search by customer name or customer address using a single pick list.  Thanks in advance!
0 Kudos