1 votos

Refreshing Python AddIn combobox => TypeError: unbound method refresh() must be called with <class> instance as first argument (got nothing instead)?

He creado un AddIn de Python de prueba minimalista usando ArcGIS 10.4.1 para Desktop, con una barra de herramientas y dos comboboxes en él.

El código (TestAddIn_addin.py y config.xml) aparece al final de esta pregunta y cuando se instala su interfaz es la siguiente:

enter image description here

Haciendo clic en la flecha hacia abajo junto a:

  • ComboBox1 ofrece dos opciones: item1 y item2
  • ComboBox1 ofrece dos opciones: item3 y item4

Esto es una simplificación de lo que quiero hacer en la práctica, pero en la prueba cuando elijo item1 o item2 del ComboBox1 quiero que su onSelChange para cambiar las opciones ofrecidas por ComboBoxClass2 para que sean A , B y C . El fragmento de código para hacer precisamente eso en la clase ComboBoxClass1 es:

def onSelChange(self, selection):
    ComboBoxClass2.items = ["A","B","C"]
    ComboBoxClass2.refresh()

Lo anterior parece coincidir con la respuesta a ¿Refrescar el Combobox del complemento Python de ArcPy?

Sin embargo, cuando pruebo este AddIn de Python desde ArcMap con la ventana de Python abierta obtengo un error:

Traceback (última llamada más reciente): Archivo " C:\Users\PolyGeo\AppData\Local\ESRI\Desktop10.4\AssemblyCache {EE92FFB8-6EED-46E8-83CC-6E8DD8A293BA} \TestAddIn_addin.py ", línea 14, en onSelChange ComboBoxClass2.refresh() TypeError: unbound method refresh() must be called with ComboBoxClass2 instance as first argument (got nothing en su lugar)

Parece que quiere que pase un valor a ComboBoxClass2.refresh() y he experimentado con varias puñaladas en la oscuridad como ComboBoxClass2.refresh(self) , ComboBoxClass2.refresh(ComboBoxClass2) y ComboBoxClass2.refresh(TestAddIn_addin.combobox1) pero estos sólo tienen éxito en errores similares de la misma línea de código.

¿Alguien sabe qué valor ComboBoxClass2.refresh() ¿podría estar esperando como parámetro aquí?

ComboBoxClass2.refresh(self) mueve el error a:

Traceback (última llamada más reciente): Archivo " C:\Users\PolyGeo\AppData\Local\ESRI\Desktop10.4\AssemblyCache {EE92FFB8-6EED-46E8-83CC-6E8DD8A293BA} \TestAddIn_addin.py ", línea 14, en onSelChange ComboBoxClass2.refresh(self) TypeError: unbound method refresh() must be called with ComboBoxClass2 instance as first argument (got ComboBoxClass1)

C:\Temp\TestAddIn\Install\TestAddIn_addin.py :

import arcpy
import pythonaddins

class ComboBoxClass1(object):
    """Implementation for TestAddIn_addin.combobox1 (ComboBox)"""
    def __init__(self):
        self.items = ["item1", "item2"]
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'WWWWWW'
        self.width = 'WWWWWW'
    def onSelChange(self, selection):
        ComboBoxClass2.items = ["A","B","C"]
        ComboBoxClass2.refresh()
    def onEditChange(self, text):
        pass
    def onFocus(self, focused):
        pass
    def onEnter(self):
        pass
    def refresh(self):
        pass

class ComboBoxClass2(object):
    """Implementation for TestAddIn_addin.combobox2 (ComboBox)"""
    def __init__(self):
        self.items = ["item3", "item4"]
        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

C:\Temp\TestAddIn\config.xml :

<ESRI.Configuration xmlns="http://schemas.esri.com/Desktop/AddIns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Name>Python Addin</Name><AddInID>{ee92ffb8-6eed-46e8-83cc-6e8dd8a293ba}</AddInID><Description>New Addin</Description><Version>0.1</Version><Image /><Author>Untitled</Author><Company>Untitled</Company><Date>09/02/2016</Date><Targets><Target name="Desktop" version="10.1" /></Targets><AddIn language="PYTHON" library="TestAddIn_addin.py" namespace="TestAddIn_addin"><ArcMap>
    <Commands>
        <ComboBox caption="ComboBox1" category="Python Addin" class="ComboBoxClass1" id="TestAddIn_addin.combobox1" itemSizeString="WWWWWW" message="" rows="4" sizeString="WWWWWW" tip=""><Help heading="" /></ComboBox>
        <ComboBox caption="ComboBox2" category="Python Addin" class="ComboBoxClass2" id="TestAddIn_addin.combobox2" itemSizeString="WWWWWW" message="" rows="4" sizeString="WWWWWW" tip=""><Help heading="" /></ComboBox>
        </Commands>
    <Extensions>
        </Extensions>
    <Toolbars>
        <Toolbar caption="Toolbar" category="Python Addin" id="TestAddIn_addin.toolbar" showInitially="true"><Items><ComboBox refID="TestAddIn_addin.combobox1" /><ComboBox refID="TestAddIn_addin.combobox2" /></Items></Toolbar>
        </Toolbars>
    <Menus>
        </Menus>
    </ArcMap></AddIn></ESRI.Configuration>

1voto

UnkwnTech Puntos 21942

Para que esto funcione, he añadido dos líneas de código al archivo __init__ función de la clase ComboBoxClass2 :

class ComboBoxClass2(object):
    """Implementation for TestAddIn_addin.combobox2 (ComboBox)"""
    def __init__(self):
        self.items = ["item3", "item4"]
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'WWWWWW'
        self.width = 'WWWWWW'

para que se convierta en:

class ComboBoxClass2(object):
    """Implementation for TestAddIn_addin.combobox2 (ComboBox)"""
    def __init__(self):
        self.items = ["item3", "item4"]
        self.editable = True
        self.enabled = True
        self.dropdownWidth = 'WWWWWW'
        self.width = 'WWWWWW'
        global secondComboBox
        secondComboBox = self

y luego en mi ComboBoxClass1 clase que cambié:

def onSelChange(self, selection):
    ComboBoxClass2.items = ["A","B","C"]
    ComboBoxClass2.refresh("TestAddIn_addin.combobox2")

a:

def onSelChange(self, selection):
    secondComboBox.items = ["A","B","C"]
    secondComboBox.refresh()

En otras palabras, y con la ayuda de @NathanW, hice la instancia de la clase ComboBox2 que estaba usando en un global llamado secondComboBox y luego refrescar eso dentro de la clase ComboBox1 .

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X