ArcMap Python Add In Extension does not execute

1888
6
10-12-2016 10:03 AM
danashney
New Contributor III

ArcMap Desktop 10.2, Windows 7, Python 2.7.3

Attempting to set up a very basic add in extension for testing. I have used the Add In Wizard to establish the project folders/ files, run makeaddin.py and then run the .esriaddin to install the add in.

This is intended to open a message box and print a message to the python immediate window upon opening the mxd but I get nothing. It doesn't error out. It just never kicks off. I can see the Add In under Customize in the mxd. 

Except for selecting the openDocument method I left all other inputs at the defaults. I've also tried this with the startup method and got the same non-result.  

Here is my script (indents not enforced):

import arcpy
import pythonaddins

class ExtensionClass1(object):
"""Implementation for TEST_addin.extension2 (Extension)"""
def __init__(self):
# For performance considerations, please remove all unused methods in this class.
self.enabled = True
def openDocument(self):
pythonaddins.MessageBox("blah blah blah TEST")
print "fake fake fake"

Any ideas here would be great. This is supposed to be the "easy" part as I haven't gotten into the complexities of my actual script that I'll be setting up at all. 

FOLLOW UP:

 Add ins are terrible to test. All testing must be done in the IDE as you are given no indication whatsoever what is wrong once you are working in ArcMap. I still have not really figured out all of the vagaries regarding why or why not something will not fire. For example, I have gotten the above script to run when I incorporate newDocument() above openDocument() with the same functional code, but if I then comment out newDocument it stops working. Nonsense. 

It comes down to this: if you can see the Add in but not the Extension (assuming its an extension) then something is wrong with your script. However, I now have a new script which runs fine directly from the ArcMap immediate window but does nothing through the Add in. Nonsense. I suppose I'll just keep randomly guessing until it happens to work. 

6 Replies
DarrenWiens2
MVP Honored Contributor

Sorry for recycling the same old instructions I've posted here, but it does work for me:

1.) Make your extension in the add-in wizard

2.) Customize the code:

import arcpy
import pythonaddins

class ExtensionClass1(object):
    """Implementation for addin_test_addin.extension2 (Extension)"""
    def __init__(self):
        # For performance considerations, please remove all unused methods in this class.
        self.enabled = True
    def startup(self):
        pythonaddins.MessageBox('Startup!', 'INFO', 0)
    def openDocument(self):
        pythonaddins.MessageBox('Open document!', 'INFO', 0)

3.) Install the add-in

4.) Open ArcMap and enable the extension:

5.) Open a document to test the openDocument method. Restart ArcMap to test the startup method. They both work for me.

I did notice one tricky part, and completely agree with your point that debugging add-ins is a pain. Once you've made the .esriaddin file by running makeaddin.py, the .esriaddin file does not automatically update itself. So, you need to run makeaddin.py and then .esriaddin if you want to see your new changes take effect in ArcMap.

LukeWebb
Occasional Contributor III

I have found testing to be 1000x easier since I installed my Add-in using a network location, instead of manually!

1) Delete the add-in if you already installed it.

2) Customise --> Add-in manager --> Options --> Search for additional add-ins in these folders"

3) Add the location that your "makeaddin.py" creates the .esriaddin file as a location. 

4) Now, if you run "makeaddin.py", then reboot arcmap, you are using the latest version of the code without having to do an extra click to install it!

RebeccaStrauch__GISP
MVP Esteemed Contributor

Luke,I have fewer steps that works well.

  1. first time, run makeaddin.py, then double clicke the <addin>.esriaddin   Make sure it is checked on.
  2. after changes to the script (but not to the toolbox itself)
    1. run make makeaddin.py
    2. without closing the Map/Catalog,    Customize->Add From File->double-click the .esriaddin file
    3. I can do this without having to close my map/catalog (which ever it was built for)
  3. If you change the Toolbar itself, the above will work but you do need to close and reopen

Just another option.  Saves quite a bit of time when making tweaks, testing, repeat.

Reminder for those that do have to close/reopen your map/catalog often when testing tools or running lots of scripts or tools....make sure to clear out your Results tab often...then close and reopen.  All those results have to be saved and then re-read in every time you close/reopen.  Keeping it cleaned out can significantly increase the close/open process.  Just a tip.

0 Kudos
danashney
New Contributor III

Thanks for the feedback all. You represent it as being obvious and strait forward, which it should be but it simply does not work. Darren, I have recreated your simple add in exactly and sometimes it installs correctly and shows up in extensions, others not. Seems like it depends on how I tilt my head. I've gotten to where I take it all the way back to the Addin Assitant every time since it seems like things get hung when I try to make in line changes.

Here is the current iteration of what I'm actually trying to accomplish. If I input say, the newDocument() function directly into the ArcMap immediate window it does exactly what it is supposed to. If I install it as an add in it never shows up in the extensions.

This repoints layers from an old server to a new one.

import arcpy
import pythonaddins
import os

class serverUpdater(object):
    """Implementation for Server_Updater_addin.extension2 (Extension)"""
    def __init__(self):
        # For performance considerations, please remove all unused methods in this class.
        self.enabled = True
    def newDocument(self):
        connections = my directory
        modeling_PROD1 = sde connection
        PROD1_connection = os.path.join(connections,modeling_PROD1)

        counter = 0

        mxd = arcpy.mapping.MapDocument("CURRENT")
        for lyr in arcpy.mapping.ListLayers(mxd):
            if lyr.supports("SERVICEPROPERTIES") and lyr.serviceProperties['Server'] == "BESDBTEST1":
                print lyr.name
                name = lyr.dataSource.split(".")[-1]
                lyr.replaceDataSource(PROD1_connection,"SDE_WORKSPACE", name)
                print "Replaced source for: " + lyr.name
                counter = counter + 1

     if counter > 0:
      arcpy.RefreshTOC()
      arcpy.RefreshActiveView()
      mxd.save()
      pythonaddins.MessageBox("BESDBTEST1 sources have been re-sourced to BESDBPROD1;  see python window for details","SERVER SOURCE UPDATE",0)

 def openDocument(self):
        connections = my directory
        modeling_PROD1 = sde connection
        PROD1_connection = os.path.join(connections,modeling_PROD1)

        counter = 0

     mxd = arcpy.mapping.MapDocument("CURRENT")
        for lyr in arcpy.mapping.ListLayers(mxd):
            if lyr.supports("SERVICEPROPERTIES") and lyr.serviceProperties['Server'] == "BESDBTEST1":
                print lyr.name
                name = lyr.dataSource.split(".")[-1]
                lyr.replaceDataSource(PROD1_connection,"SDE_WORKSPACE", name)
                print "Replaced source for: " + lyr.name
                counter = counter + 1

     if counter > 0:
      arcpy.RefreshTOC()
      arcpy.RefreshActiveView()
      mxd.save()
      pythonaddins.MessageBox("BESDBTEST1 sources have been re-sourced to BESDBPROD1;  see python window for details","SERVER SOURCE UPDATE",0)

UPDATE

 - I got it to show up in the Extensions but when I attempt to run it through the event (open/newDocument) I get...nothing. The way I got it to at least show up in Exentions was to drop it into pyScripter instead of Notepadd ++ which gave me different syntax errors regarding indentation. Had to unindent and re-indent back to, as far as I could tell, the exact same spot but it cleaned it up. Anyway, I'm done with trying for the event extension. I set it up to run from a button instead which works.

My 2 cents: Add ins Extensions are majorly broken in their current configuration. There is absolutely no error handling whatsoever for extensions from what I saw. I at least got minimal error messaging when working on the button. Testing consists of attempting to run it, seeing nothing happen, then going back to the script for a round of randomly guessing what could be the issue. I would not recommend this tool to anyone. I've sunk a ridiculous amount of time into doing something that at its face should be strait forward.

Thanks to everyone who attempted to help.  

LukeWebb
Occasional Contributor III

If you had issues with indentation in pyscripter using your notepad ++ file, it sounds like you have got your notepad setup wrong for python!

The problem is, you are mixing "Tabs" with "Spaces"

To fix --> 

Open notepad ++ 

"Settings" --> "Preferences" --> "Language Menu / Tab Settings"

Find Python

On the right, tick the box "replace by space" and choose a number of spaces.

Now when you use tab, it will behind the scenes put in spaces, and make sure that what you see is exactly as python will read the indentation.

danashney
New Contributor III

Thanks Luke. 

0 Kudos