Python-Addin On/Off-button

5909
6
03-13-2013 09:48 AM
KarstenRank
Occasional Contributor III
Hello,

is it possible to build an on/off-button in a toolbar, that activates a different toolbar. I tried the following snippet:

class ButtonClass5(object):
    """Implementation for GLADIS_Hilfe_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        counter += 1
        status = counter % 2
        if counter == 1:
            (id of the toolbar).enable = True
        elif:
            (id of the toolbar).enable = False
        pass


Is this possible, or can I only enable buttons?

Thanks a lot,


Karsten
Tags (2)
0 Kudos
6 Replies
JohnDye
Occasional Contributor III
So, I'm not sure why you're implementing a counter, but I would do just a simple toggle like this.
class ButtonClass5(object):
    """Implementation for GLADIS_Hilfe_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        if ToolbarID.enabled == True:
            ToolbarID.enabled == False
            ToolbarID.refresh()
        elif ToolbarID.enabled == False:
            ToolbarID.enabled = True
            ToolbarID.refresh()
        else:
            pass

Also it looks like you have a little bit of confusion with the ID, you're setting youself up for a name collision down the road. Based on how you've set up your ID for this button, you're going to have a bunch of buttons with the same ID, in this case, ".button". That's going to result in your Config XML not know which Class to call when it tries to execute the logic. You don't really even need the button part because the fact that it is a button is already encapsulated in the ellipsis at the end "(Button)""". I would suggest you change it to something like:
 """Implementation for GLADIS.Hilfe (Button)"""

Your ID in this case being "Hilfe" which you would enable by calling:
Hilfe.enabled == True


The ID comes after the period, everything before that is just a namespace and is not part of the ID. Also remember that your ID is not the same as the Class. In the case of your button, the Class is "ButtonClass5" while the ID is ".button". I got tripped up by that just last week.

I did some posts on this kind of stuff just a little while ago. You might find them helpful.
http://forums.arcgis.com/threads/78771-Use-Selection-of-one-Combobox-to-update-the-items-list-in-ano...
http://forums.arcgis.com/threads/66739-Python-Addin-Action-based-on-Property-Value?highlight=Python+...
0 Kudos
JonPedder
Occasional Contributor II
In a similar vein I have a Toggle on/off feature that turns on or off attributes in the database. I�??ve been searching for a way to change the color (icon) on the button depending whether the feature is ON or OFF.
Eg. Feature is on, button turns green, Feature is off button turns red.

This might be beyond the scope of the python-addin and would need to be done in objects I�??d guess.

Any thoughts?

Cheers

Jon
0 Kudos
JohnDye
Occasional Contributor III
So, there's a way to designate whether or not a button appears activated or not. You would do that with the checked property.
To make the button appear activated, you would just toggle the checked property like so along with your toolbar enabled state.
import arcpy
import pythonaddins

class ToolbarToggle(object):
    """Implementation for GLADIS.Hilfe (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        if ToolbarID.enabled == True:
            ToolbarID.enabled = False
            self.checked = False
            ToolbarID.refresh()
        elif ToolbarID.enabled == False:
            ToolbarID.enabled = True
            self.checked = True
            ToolbarID.refresh()
        else:
            pass

As for actually swapping out the icon, green for active, red for inactive, that's not really possible using anything ESRI provides in ArcPY or the Python Addin Module. At least, not that I've seen. I wondered the same myself and ended up posting the suggestion on the ArcGIS Ideas Site.

I thought about maybe defining a function in a script which changes the file path in the Config.xml where the path to the icon is stored, and call that function at the end of the OnClick function, to swap file path for icon, depending on the enabled state and then call the refresh() function for the button. However, it appears that the Config.xml and the Python Script are only referenced on initialization. I'm pretty sure that during initialization, your script logic and Config.xml parameters are used to build an assembly file, which is what is actually being referenced by ArcGIS to perform the functions. This makes sense because if ArcGIS were actually referencing the Config.xml and Python Script, you would be able to just make changes on the fly without having to restart ArcGIS everytime and reinstall the addin. Instead, the assembly has to be rebuilt and reinstalled for changes to take effect.
RebeccaStrauch__GISP
MVP Emeritus

John, I realize this is an old post, but I went to vote up your idea, and of course it is still pointing to the old site. No you know the title to search, or can you post the link to the new site ArcGIS Ideas ?  If it was implemented and not there anymore, all the better.

0 Kudos
JohnDye
Occasional Contributor III

Hi Rebecca,

I've reposted it but I doubt it can actually go anywhere because of how python addins work and also Esri's development priorities.

So the way a python addin works is that on initialization, ArcMap/Catalog/whatever your target application is, extracts the contents from the .esriaddin file - which is actually just a zip file (seriously, change the extension to from .esriaddin to .zip, open it up and you'll see all your addin files). Anyway, Esri extracts the contents of it to your application's Assembly Cache. For ArcMap on Windows 7 for example, this is the directory C:\Users\<username>\AppData\Local\ESRI\Desktop<version>\AssemblyCache. There's a catch however. It doesn't extract everything in the .esriaddin file to your assembly cache, only the contents of the install folder. So your images folder and config.xml, those don't get extracted. I assume they get loaded into the target application's address space (memory), ArcMap.exe for instance.

So without the config.xml and your image files sitting in your assembly cache or somewhere else on disk for you to modify and the target application such as ArcMap continually checking those files for updates or addins having some kind of reload function, it's pretty much impossible to do this with the current architecture of Python Addins - as I understand them.

That said, Esri could fix it. I'd bet money they won't, though. Esri isn't dedicating very many development resources to keeping Python Addins going these days. You can witness that in the fact that new releases of ArcGIS for Desktop haven't really added any functionality to python addins since they first came out. You might have also noticed that Python Addins for ArcGIS Pro is not actually even a thing. If you want to develop Python Addins for Pro, .NET is your only option. I asked an Esri associate about this at the DevSummit this year and got a pretty amusing response; "We're waiting to see if there's actually any demand for that.".

I've posted two new ideas:

Create a reload function for Python Addins

Support Python Addins in ArcGIS Pro

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Hi John, I was out of the office and this got lost in the pile of unread emails.  I voted both ideas up, and also posted a workaround of sorts to the reload button, which I'll also include here.

I find the fastest way to refresh addins when developing (i.e. after a .updating a .py) without having to close/open Catalog/Map is to

  1. run (double-click) make addin.py
  2. Right-click in gray area or use the Customize-CustomizeMode
  3. Highlight your addin (although this might not be necessary)
  4. "Add from File" and select <your addin>.esriaddin file.  

That loads the update addin without having to close the ArcGIS Desktop session which saves a lot of time.  And it at least remembers this path if you are editing the same addin over and over.  So not a wonderful solution, but as often as I "repeat" when working on addins, saving 15-60+ seconds each time reduces my frustration.

If there was a way to create a button that enters the Customize Mode and loads from a file, that would make this process work, but I don't know if that is possible.

0 Kudos