1

I'm using ArcGIS 10.2.1 and have written an Arcpy addin with multiple comboboxes and an "Unselect" button. The comboboxes run queries on the data and the button clears the selections.

I need the "Unselect" button to clear the comboboxes of their entries. I've tried both of these options:

1) Self.Editable=False, then the selection in the comboboxes disappear when the user selects something. That's what I posted this question in regards to.

2) Self.Editable=True, then the selection remains visible, but I can't get it to clear when the "Unselect" button is clicked, even when the selection is cleared. (Code below)

So, edit=true, can't get the unselect to clear the combobox, edit = false, the selection in the combobox automatically disappears. Frustrating, huh? Any other thoughts?

class ButtonUnselect(object):
"""Implementation for Walla_Walla_QueryTool_addin.button (Button)"""
def __init__(self):
    self.enabled = True
    self.checked = False
def onClick(self):
    self.mxd = arcpy.mapping.MapDocument('current')
    lyr = arcpy.mapping.ListLayers(self.mxd, "PODs")[0]
    lyr2 = arcpy.mapping.ListLayers(self.mxd, "POUs")[0]
    lyr3 = arcpy.mapping.ListLayers(self.mxd, "Management_Points")[0]
    arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
    arcpy.SelectLayerByAttribute_management(lyr2, "CLEAR_SELECTION")
    arcpy.SelectLayerByAttribute_management(lyr3, "CLEAR_SELECTION")
    df = arcpy.mapping.ListDataFrames(self.mxd)[0]
    df.extent = ext
    ext = lyr2.getExtent()
    combobox_2.__init__

class ComboBoxPurpose(object):
"""Implementation for Walla_Walla_QueryTool_addin.combobox_5 (ComboBox)"""
def __init__(self):
    self.editable = True
    self.enabled = True
    self.dropdownWidth = 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWW'
    self.width = 'WWWWWWWWWWWWWWWWWW'
def onSelChange(self, selection):
    self.mxd = arcpy.mapping.MapDocument('current')
    layer1 = arcpy.mapping.ListLayers(self.mxd, "PODs")[0]      
    layer2 = arcpy.mapping.ListLayers(self.mxd, "POUs")[0]
    arcpy.SelectLayerByAttribute_management(layer1, "NEW_SELECTION", "Purpose = '" + selection + "'")
    arcpy.SelectLayerByAttribute_management(layer2, "NEW_SELECTION", "Purpose = '" + selection + "'")
    arcpy.RefreshActiveView()
    df = arcpy.mapping.ListDataFrames(self.mxd)[0]
    layer1.getSelectedExtent()
    layer2.getSelectedExtent()
    df.zoomToSelectedFeatures()
def onEditChange(self, text):
    pass
def onFocus(self, focused):
    self.mxd = arcpy.mapping.MapDocument('current')
    layer3 = arcpy.mapping.ListLayers(self.mxd, "PODs")[0]
    self.items = []
    values = [row[0] for row in arcpy.da.SearchCursor(layer3, ["Purpose"])]
    for uniqueVal in sorted(set(values)):
                self.items.append(uniqueVal)
def onEnter(self):
    pass
def refresh(self):
    pass

Any thoughts would be greatly appreciated!

3

So, just to follow up on what Luke said, I created (see below) a very simple example that makes a pull-down of current map layers, which can be easily modified to list something else and act on the selection.

The workaround mentioned executes with onEnter so that the last selected val is reset in the combobox. Some comments and print statements left in for your further testing convenience.


I added code (a button class, as you specified) that 'clears' the value of the combobox. The 'refresh' function is called in the button class from the combobox class - that's an important distinction, why I chose to add to the code (refresh is called 'internally' by the combobox class as well as 'externally' by the button class).

import arcpy
import pythonaddins

class ButtonClass7(object):
    """Implementation for testNonEditCombo_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        combobox.value = ''
        combobox.refresh()

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

    def __init__(self):
        self.editable = True
        self.enabled = True
        # introducing global
        global staticVal
        self.newfunction()
        self.value = staticVal = self.items[0]

    def onSelChange(self, selection):
        # redefining global
        global staticVal
        self.value = staticVal = selection
        print 'selection: {0}'.format(selection)

    def onEditChange(self, text):
        # I toyed with this function but decided not to use it in this example.
        pass

    def onFocus(self, focused):
        # if any layers are added/removed from the TOC, the list is refreshed.
        if focused: self.newfunction()

    def onEnter(self):
        self.value = staticVal
        print 'self.refresh...so did the refresh function fire?'
        self.refresh()

    def refresh(self):
        arcpy.RefreshActiveView()
        print 'refreshed...'

    def newfunction(self):
        self.mxd = arcpy.mapping.MapDocument('current')
        self.items = [lyr.name for lyr in arcpy.mapping.ListLayers(self.mxd)]
  • Hi Wayne, I edited my original question above to clarify things. Basically, I tried the answer you proposed at the start, but it resulted in a different problem - not allowing me to clear the combobox of the entry. See above and code for clarification. Any other thoughts? Shouldn't there be a combobox.clear() method in arcpy?? – user29358 May 20 '14 at 21:35
  • That completely changes the question, but to salvage this thread I will simply add to my code as I did for the code sample provided at the other forum post. – T. Wayne Whitley May 21 '14 at 0:03
2

You are calling refresh() but according to the documentation, the method is Refresh() (python is case sensitive).

However, I couldn't get this working in 10.1 and ended up leaving the combobox editable, storing a class variable self.selection to track the selection in the onSelChange method and then resetting the value to the previous selection if a non self.items value was typed in using the onEditChange/onEnter methods.

  • Yes, this is an adequate workaround - couldn't get the editable property to work as expected at 10.2.1 either. I think the refresh() is working okay - docs are wrong. – T. Wayne Whitley May 19 '14 at 16:34
0

According to the documentation, after a change is made you must call the Refresh() method to ensure that the value is visible:

under value: This property gets or sets the value of the combo box. After setting a value, use the Refresh() method to ensure it is visible in the edit portion of the control.

Refresh: Refreshes the combo box after a value is set. Refreshing the combo box will ensure the value is visible in the edit portion of the control.

  • I have tried that - to no avail. It doesn't change anything. Thanks though, any other thoughts? – user29358 May 15 '14 at 22:26
  • I can't see that in the code supplied anywhere, though it is undoubtedly not all of the code. Are you overriding the refresh with def refresh(self):? Sorry, not familiar with python add-ins.. all mine are C#/VB.net and all my python is with geoprocessing/lasPY/GDAL. – Michael Stimson May 15 '14 at 22:31
  • I did try that...but it didn't change anything. I'll update my code above to reflect that. – user29358 May 15 '14 at 23:40
  • Perhaps try just a simple combobox that does nothing to test the behavior so the other code doesn't get in the way. – Michael Stimson May 15 '14 at 23:52

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.