I am developing a Python Add-in for ArcMap 10.4 that, upon a click on a map, opens a wxPython GUI that contains a combo box listing the layers in the map document.
Here's a current snippit from my script:
class ToolClass2(object):
"""Implementation for DesignTool.tool (Tool)"""
dlg= None
def __init__(self):
self.enabled = True
self.shape = "NONE" # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
self.cursor=3 #set cursor to crosshair
def onMouseDownMap(self, x, y, button, shift):
global xy
xy = (x,y)
global layerlist
layerlist=[]
mxd=arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
layerlist.append(lyr.name)
del mxd
I then reference layerlist within my wxpython class to have the layers display as choices within the combo box. When I run it for the first time after opening ArcMap, it runs correctly and displays all of the layers within the map document. However, when I attempt to run it again after adding or deleting layers, it does not update the list - even if I start a new blank document.
How can I write my script to update upon each run of the tool?
I am just assuming that this is an issue with my map document, but perhaps it is an issue with my WxPython dialog?
UPDATE: I now believe that this issue is coming from the fact that the self.Destroy() command in wxPython does not work in ArcMap. As a workaround for this, I was using self.Show(False) to close the UI (similar to an example shown here: https://geonet.esri.com/thread/38336), but when run again, self.Show(True) displays the same UI, as it was never actually destroyed. Are there any known alternatives to self.Destroy() that will actually get rid of the UI and not just prevent it from being displayed?
import arcpy
import pythonaddins
import wx
class ToolClass2(object):
"""Implementation for DesignTool.tool (Tool)"""
dlg= None
def __init__(self):
self.enabled = True
self.shape = "NONE" # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
self.cursor=3 #set cursor to crosshair
def onMouseDownMap(self, x, y, button, shift):
global laylist
laylist=[]
mxd=arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
laylist.append(lyr.name)
del mxd
if self.dlg is None:
self.dlg = TestDialog()
else:
self.dlg.Show(True)
return
class TestDialog(wx.Frame):
def __init__(self):
wxStyle = wx.CAPTION | wx.RESIZE_BORDER | wx.MINIMIZE_BOX |wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.CB_DROPDOWN
wx.Frame.__init__(self, None, -1, "Design Form", style=wxStyle, size=(330, 370))
self.SetMaxSize((330, 370))
self.SetMinSize((330, 370))
self.Bind(wx.EVT_CLOSE, self.OnClose)
panel = wx.Panel(self, -1)
wx.StaticText(panel, -1, "Choose Layer:", pos=(8,64))
self.LayerCombo = wx.ComboBox(panel, -1, value=laylist[1], pos=(180, 64), size=(120,21), choices=laylist)
self.Bind(wx.EVT_BUTTON, self.OnSet, id=self.btnSet.GetId())
self.Show(True)
def OnClose(self, event):
self.Show(False) # self.Destroy() doesn't work
def OnSet(self, event):
Layerpath= str(self.LayerCombo.GetValue())
self.Show(False)
app = wx.PySimpleApp()
app.MainLoop()