0

I have two combo boxes. I am trying to add items dynamically into the second combobox from the first combobox's onSelChange(self, selection) event. due to some reason, this is not working.

Here is my sample code:

import arcpy
import pythonaddins
class ComboBoxClass1(object):
 """Implementation for TestCombo_addin.combobox (ComboBox)"""
 def __init__(self):
 self.items = ["cb1item1", "cb1item2"]
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWW'
 self.width = 'WWWWWW'
 self.cb2=ComboBoxClass2()
 def onSelChange(self, selection):
 pythonaddins.MessageBox(selection,"Message",0)
 self.cb2.items.append(selection)
 self.cb2.refresh()
 def onEditChange(self, text):
 pass
 def onFocus(self, focused):
 pass
 def onEnter(self):
 pass
 def refresh(self):
 pass
class ComboBoxClass2(object):
 """Implementation for TestCombo_addin.combobox_1 (ComboBox)"""
 def __init__(self):
 self.items = ["cb2item1", "cb2item2"]
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWW'
 self.width = 'WWWWWW'
 def onSelChange(self, selection):
 pass
 def onEditChange(self, text):
 pass
 def onFocus(self, focused):
 pass
 def onEnter(self):
 pass
 def refresh(self):
 pass
PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Jan 29, 2018 at 17:51

2 Answers 2

0

I think setting a hook to a class instance to be accessed through a class property (as opposed to a property of an instance of that class) is bad practice and while it works fine here will cause you grief if you use this construct in other code.

E.g. If you write a class and create more than one instance of it, the hook property of the class will get overwritten each time an instance is created.

What I do is use the instances of the classes, not the classes themselves.

For example, in config.xml you will have something like:

<?xml version="1.0"?>
<ESRI.Configuration etc...>
 <etc...>
 <AddIn language="PYTHON" library="ComboBox_addin.py" namespace="ComboBox_addin">
 <ArcMap>
 <Commands>
 <ComboBox caption="CB1" category="Blah" class="ComboBoxClass1" id="ComboBox_addin.combobox1" etc...>etc...</ComboBox>
 <ComboBox caption="CB2" category="Blah" class="ComboBoxClass2" id="ComboBox_addin.combobox2" etc...>etc...</ComboBox>
 </Commands>
 <Extensions></Extensions>
 <Toolbars>
 <Toolbar caption="Blah blah" category="Blah" id="ComboBox_addin.toolbar" showInitially="true">
 <Items>
 <ComboBox refID="ComboBox_addin.combobox1"/>
 <ComboBox refID="ComboBox_addin.combobox2"/>
 </Items>
 </Toolbar>
 </Toolbars>
 <Menus></Menus>
 </ArcMap>
 </AddIn>
</ESRI.Configuration>

Note the id and refID are the same. These will refer to instances of these classes.

Then you just replace references to ComboBoxClass2 to combobox2 in your code:

import arcpy
import pythonaddins
class ComboBoxClass1(object):
 """Implementation for ComboBox_addin.combobox1 (ComboBox)"""
 def __init__(self):
 arcpy.env.workspace = r"C:\polygeo\QGIS"
 self.items = arcpy.ListFeatureClasses()
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWWWWWWWWWWWWWWWWWWWWWWWW'
 self.width = 'WWWWWWWWWWWWWWWWWWWWWWWWWWWW'
 def onSelChange(self, selection):
 combobox2.items = [x.name for x in arcpy.ListFields(selection)] # <================
 def onEditChange(self, text):
 pass
 def onFocus(self, focused):
 pass
 def onEnter(self):
 pass
 def refresh(self):
 pass
class ComboBoxClass2(object):
 """Implementation for ComboBox_addin.combobox2 (ComboBox)"""
 def __init__(self):
 self.items = []
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWWWWWWWW'
 self.width = 'WWWWWWWWWWWW'
 def onSelChange(self, selection):
 pass
 def onEditChange(self, text):
 pass
 def onFocus(self, focused):
 pass
 def onEnter(self):
 pass
 def refresh(self):
 pass

If you run into a NameError (an issue with earlier ArcGIS versions, not sure if still a problem), put the following at the bottom of ComboBox_addin.py: :

##Workaround for 'NameError: global name 'combobox2' is not defined' - https://geonet.esri.com/thread/76833
combobox1 = ComboBoxClass1()
combobox2 = ComboBoxClass2()
answered Oct 31, 2018 at 2:36
-1

I got a solution (Thanks to Freddie Gibson from ESRI.) I am curious to know if there are other solutions.

import arcpy
import pythonaddins
class ComboBoxClass1(object):
 """Implementation for TestCombo_addin.combobox (ComboBox)"""
 def __init__(self):
 self.items = ["cb1item1", "cb1item2"]
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWW'
 self.width = 'WWWWWW'
 ComboBoxClass1._hook=self
 def onSelChange(self, selection):
 pass
class ComboBoxClass2(object):
 """Implementation for TestCombo_addin.combobox_1 (ComboBox)"""
 def __init__(self):
 self.items = ["cb2item1", "cb2item2"]
 self.editable = True
 self.enabled = True
 self.dropdownWidth = 'WWWWWW'
 self.width = 'WWWWWW'
 def onSelChange(self, selection):
 ComboBoxClass1._hook.items.append(selection)
answered Feb 9, 2018 at 18:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.