0

I am attempting my very first python add in. what I would like it to do is look at a feature class, look through the town field. when the user selects a town I want the next combo box to populate with the LABELTEXT field with all of the values in that town and when a LABELTEXT is selected zoom to that bad boy.

I dont know how to get the town return into the ComboClass2 class or build the query to filter based on the town result

class ComboBoxClass1(object):  
    """Implementation for addin2_addin.combobox (ComboBox)"""  


    def __init__(self):  
        self.editable = True  
        self.enabled = True  
        self.dropdownWidth = 'WWWWWWWWWWWWWWWW'  
        self.width = 'WWWWWWWWWWWWWWWW'  


    def onSelChange(self, selection):  
        layer = arcpy.mapping.ListLayers(mxd, "block_cards", df)[0]  
        a = arcpy.SelectLayerByAttribute_management(layer, "NEW_SELECTION", "town = '" + selection + "'""'") 
        return a 
        df.extent = layer.getSelectedExtent() 
        arcpy.RefreshActiveView() 


    def onFocus(self, focused): 
        global mxd 
        mxd = arcpy.mapping.MapDocument('current') 
        global df 
        df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0] 
        layer = arcpy.mapping.ListLayers(mxd, "block_cards", df)[0] 
        arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION") 
        self.items = [] 
        values = [row[0] for row in arcpy.da.SearchCursor(layer, ["town"])] 
        for uniqueVal in sorted(set(values)): 
            self.items.append(uniqueVal) 


class ComboBoxClass2(object): 
    """Implementation for addin2_addin.combobox (ComboBox)""" 


    def __init__(self): 
        self.editable = True 
        self.enabled = True 
        self.dropdownWidth = 'WWWWWW' 
        self.width = 'WWWWWW' 


    def onSelChange(self, selection): 
        layer = arcpy.mapping.ListLayers(mxd, "block_cards", df)[0] 
        arcpy.SelectLayerByAttribute_management(layer, "NEW_SELECTION", "town = '" + ComboBoxClass1.onSelChange() + "' AND LABELTEXT = '" + selection + "'" )  
        df.extent = layer.getSelectedExtent()  
        arcpy.RefreshActiveView()  


    def onFocus(self, focused):  
        global mxd  
        mxd = arcpy.mapping.MapDocument('current')  
        global df  
        df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]  
        layer = arcpy.mapping.ListLayers(mxd, "block_cards", df)[0]  
        arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")  
        self.items = []  
        values = [row[0] for row in arcpy.da.SearchCursor(layer, ["LABELTEXT"])]  
        for uniqueVal in sorted(set(values)):  
            self.items.append(uniqueVal)  
1

Thank you everyone for the responses. so much better than geonet. I was able to look like a maniac with the below code.

class ComboBoxClass1(object):
    """Implementation for addin2_addin.combobox (ComboBox)"""

    def __init__(self):
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'W' * 16
        self.width = 'W' * 16
        mxd = arcpy.mapping.MapDocument("CURRENT")
        self.mxd = arcpy.mapping.MapDocument("CURRENT")
        self.df = arcpy.mapping.ListDataFrames(mxd)[0]

    def onSelChange(self, selection):
        layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]
        a = arcpy.SelectLayerByAttribute_management(layer, "NEW_SELECTION", "town = '{}'".format(selection))
        self.df.extent = layer.getSelectedExtent()
        arcpy.RefreshActiveView()

    def onFocus(self, focused):
        layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]
        arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")
        self.items = sorted(list(set(filter(None, [row[0] for row in arcpy.da.SearchCursor(layer, ["town"])]))))


class ComboBoxClass2(object):
    """Implementation for addin2_addin.combobox (ComboBox)"""

    def __init__(self):
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'W' * 6
        self.width = 'W' * 6
        mxd = arcpy.mapping.MapDocument("CURRENT")
        self.mxd = arcpy.mapping.MapDocument('current')
        self.df = arcpy.mapping.ListDataFrames(mxd)[0]


    def onSelChange(self, selection):
        layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]
        arcpy.SelectLayerByAttribute_management(layer, "NEW_SELECTION", "town = '{}' AND LABELTEXT = '{}'".format(combobox.value, selection))
        self.df.extent = layer.getSelectedExtent()
        arcpy.RefreshActiveView()


    def onFocus(self, focused):
        layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]
        arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")
        expression = "town = '{}'".format(combobox.value)
        self.items = sorted(list(set(filter(None, [row[0] for row in arcpy.da.SearchCursor(layer, ["LABELTEXT"], where_clause=expression)]))))
  • That is pretty cool, I guess I never thought of it that way. As per my post, I have always used buttons to execute the query, but I suppose that wasn't necessary after all. I never thought to build that logic right into the onSelection method. Does this work pretty fast? – crmackey Jun 5 '15 at 15:22
0

To get at the value from your ComboboxClass1 value, you need to look in the config.xml for that class and whatever is after the period is what you need to reference. Since you have more than one combobox I think you would want to make sure these classes have unique names after to period when you set up the Add-In.

EDIT:

That being said, you do not want to excecute tasks from the combobox. Instead, you may want to have the user select values from two comboboxes and then have a button to execute the query. So I would go back to the add in wizard and create a button to run it.

This is how I would do it:

import arcpy
import pythonaddins

class Query(object):
    """Implementation for addin2_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
        self.mxd = arcpy.mapping.MapDocument('current')
        self.df = self.mxd.activeDataFrame
        self.layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]

    def onClick(self):
        # select features
        arcpy.SelectLayerByAttribute_management(self.layer, "NEW_SELECTION", "town = '{}' AND LABELTEXT = '{}'".format(combobox.value, combobox_1.value)) #assuming these are the proper names
        self.df.extent = self.layer.getSelectedExtent()  
        arcpy.RefreshActiveView()

class ComboBoxClass1(object):  
    """Implementation for addin2_addin.combobox (ComboBox)"""  

    def __init__(self):  
        self.editable = True  
        self.enabled = True  
        self.dropdownWidth = 'W' * 16
        self.width = 'W' * 16

    def onSelChange(self, selection):
        mxd = arcpy.mapping.MapDocument('current')
        layer = arcpy.mapping.ListLayers(mxd, "block_cards", df)[0]  
        arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")
        self.mxd = arcpy.mapping.MapDocument('current')
        self.df = self.mxd.activeDataFrame
        self.layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]  

        arcpy.RefreshActiveView()

    def onFocus(self, focused):
        layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", df)[0] 
        self.items = sorted(list(set(filter(None, [row[0] for row in arcpy.da.SearchCursor(layer, ["town"])])))) 


class ComboBoxClass2(object): 
    """Implementation for addin2_addin.combobox (ComboBox)""" 

    def __init__(self): 
        self.editable = True 
        self.enabled = True 
        self.dropdownWidth = 'W' * 6
        self.width = 'W' * 6
        self.mxd = arcpy.mapping.MapDocument('current')
        self.layer = arcpy.mapping.ListLayers(self.mxd, "block_cards", self.df)[0]  

    def onSelChange(self, selection):
        arcpy.SelectLayerByAttribute_management(self.layer, "CLEAR_SELECTION") 
        arcpy.RefreshActiveView()

    def onFocus(self, focused):    
        self.items = sorted(list(set(filter(None, [row[0] for row in arcpy.da.SearchCursor(self.layer, ["LABELTEXT"])])))) 

You can find the combobox class names in the config.xml like this Add-In I have built in the past:

enter image description here

Here is an example of an Add-In I created in the past that finds unconnected features and uses 2 comboboxes. May not be perfect, but shows an example of using 2 comboboxes and a button:

import arcpy
import pythonaddins

class Query(object):
    """Implementation for FindUnconnectedFeatures_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        mxd = arcpy.mapping.MapDocument('Current')
        df = mxd.activeDataFrame
        targ = arcpy.mapping.ListLayers(mxd, combobox.value)[0]
        source = arcpy.mapping.ListLayers(mxd, combobox_1.value)[0]
        sel = 'INTERSECT'

        # select by location
        arcpy.SelectLayerByLocation_management(targ, sel, source)
        arcpy.SelectLayerByAttribute_management(targ, 'SWITCH_SELECTION')

class SourceLayer(object):
    """Implementation for FindUnconnectedFeatures_addin.combobox_1 (ComboBox)"""
    def __init__(self):
        self.items = []
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'W' * 12
        self.width = 'W' * 12

    def onSelChange(self, selection):
        pass
    def onEditChange(self, text):
        pass
    def onFocus(self, focused):
        if focused:
            self.mxd = arcpy.mapping.MapDocument('current')
            self.df = self.mxd.activeDataFrame
            lyrs = [l.name for l in arcpy.mapping.ListLayers(self.mxd, '*', self.df)
                    if not l.isBroken and l.supports('DATASOURCE')]
            self.items = sorted(lyrs)
            del self.mxd
    def onEnter(self):
        pass
    def refresh(self):
        pass

class TargLayer(object):
    """Implementation for FindUnconnectedFeatures_addin.combobox (ComboBox)"""
    def __init__(self):
        self.items = []
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'W' * 12
        self.width = 'W' * 12

    def onSelChange(self, selection):
        pass
    def onEditChange(self, text):
        pass
    def onFocus(self, focused):
        if focused:
            self.mxd = arcpy.mapping.MapDocument('current')
            self.df = self.mxd.activeDataFrame
            lyrs = [l.name for l in arcpy.mapping.ListLayers(self.mxd, '*', self.df)
                    if not l.isBroken and l.supports('DATASOURCE')]
            self.items = sorted(lyrs)
            del self.mxd
    def onEnter(self):
        pass
    def refresh(self):
        pass

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.