Select to view content in your preferred language

Python Addin Tool Results in Crash

3024
9
06-23-2012 09:56 AM
MikeHunter
Frequent Contributor
I think the Python addin idea is really good, but there is at least 1 show stopper right now.  I made a toolbar with a single tool to test.  Everything works fine until exactly 9 clicks with the tool, at which point arcmap crashes.  It's always 9 clicks and crash, very repeatable.  I'm running XP, SP3, and there's a single shapefile layer in the map, but I've tried it in several mxd's, and it's always the same result.  As you can see, the tool doesn't do anything except print the event args to the python window.  I'm almost certain the problem is in the onRectangle event, since the crash only occurs if self.shape is set to Rectangle.   I can set self.shape to None, and put "print self.down" in the onMouseDownMap def, and it will work all day long.  But I need rectangle for the tools I want to build. 

Below is the code. Jason or someone, if you can check this, I sure would appreciate it.  Python addins hold a lot of promise, and I'd sure like to be able to use them and get away from .NET.

import arcpy
import pythonaddins

class ToolClass2(object):
    """Implementation for ToolTest_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "Rectangle" # Can set to "Line", "Circle" or "Rectangle" 
        #for interactive shape drawing and to activate the 
        #onLine/Polygon/Circle event sinks.
        self.cursor = 3
        self.down = None
        
    def onMouseDownMap(self, x, y, button, shift):
        self.down = 'down', x, y, button, shift
    
    def onRectangle(self, rectangle_geometry):
        extent = rectangle_geometry
        
        s = ', '.join(('onrect', str(extent.XMin), str(extent.YMin), 
                        str(extent.XMax), str(extent.YMax)))
        print self.down
        print s
        self.down = None




thanks,
Mike

PS:  Once this is fixed, we need more cursors, too.  In .NET we get unlimited cursors (make your own).
Tags (2)
0 Kudos
9 Replies
NobbirAhmed
Esri Alum
Sorry Mike and thanks for pointing out the issue.

The issue is resolved and will be available in the next service pack (10.1 SP1).

Could you please elaborate on "we need more cursors" - if possible with some use cases?
0 Kudos
MikeHunter
Frequent Contributor
Sorry Mike and thanks for pointing out the issue.

The issue is resolved and will be available in the next service pack (10.1 SP1).

Could you please elaborate on "we need more cursors" - if possible with some use cases?


Well, it's good you guys got it fixed, but until the SP comes out, we're dead in the water here.  How about a patch?

As far as cursors go, with .NET, we use .cur files, which are available in a number of places and are easy enough to make yourself.  I've got a several of them that I've made over the years for .NET tools, and I was hoping to just transfer them to the Python addins.  If we can't get that, then what I need are cursors similar to the hyperlink tool cursor, the identify tool cursor, and several other crosshair type cursors.  The Python addin cursors available now are pretty limited. 

Thanks,
Mike
0 Kudos
NobbirAhmed
Esri Alum
There is a workaround for the crash. Create a tool for one of the geometry types - in there, in OnMouseDownMap create a point its x, y parameters. In OnMouseUpMap create another point. Essentially, you will click a point, hold down the mouse and release it at another location. Your rectangle will be created with these two points as opposite corner. In case of a circle, the first point will be the center and distance between two points will be the radius.

Here is my code for rectangle class:

class RectangleToolClass(object):

    """Implementation for AlternativeGeometries_addin.rect_tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "NONE" 

    def onMouseDownMap(self, x, y, button, shift):
        self.point1 = arcpy.Point(x, y)

 
    def onMouseUpMap(self, x, y, button, shift):
        self.point2 = arcpy.Point(x, y)
        array = arcpy.Array()
        array.add(self.point1)
        array.add(arcpy.Point(self.point2.X, self.point1.Y))
        array.add(self.point2)
        array.add(arcpy.Point(self.point1.X, self.point2.Y))
        array.add(self.point1)
        g = arcpy.Polygon(array)
        arcpy.CopyFeatures_management(g, r"in_memory\rectangle")


Your onMouseUp method for circle could be:

    def onMouseUpMap(self, x, y, button, shift):
        self.point2 = arcpy.Point(x, y)
        pt1 = arcpy.PointGeometry(self.point1)
        pt2 = arcpy.PointGeometry(self.point2)
        buff_dist = pt1.distanceTo(pt2)
        arcpy.Buffer_analysis(pt1, r"in_memory\circle", buff_dist)


The line is simplest 🙂

    def onMouseUpMap(self, x, y, button, shift):
        self.point2 = arcpy.Point(x, y)
        array = arcpy.Array()
        array.add(self.point1)
        array.add(self.point2)
        g = arcpy.Polyline(array)
        arcpy.CopyFeatures_management(g, r"in_memory\line")
0 Kudos
MikeHunter
Frequent Contributor
Nobbir, I thought of that myself, and it's easy enough.  But the problem is the user does not get any feedback on the screen that a rectangle is being drawn unless you set shape='Rectangle'.  But if you do that, onMouseUpMap does not fire.   A patch would be nice.

thanks
Mike
0 Kudos
NobbirAhmed
Esri Alum
I have conveyed your request about a patch to the team.

Yes, you don't get any feedback 😞 - just bear with it for the time being.
0 Kudos
MikeHunter
Frequent Contributor
Nobbir, thanks for all the help.  I am very eager to start using Python addins and am sure they are going to be a big benefit. Hopefully, at some point soon, we will be able to use wxPython inside the app process.  Again, thanks for your good work.

Mike
0 Kudos
NobbirAhmed
Esri Alum
Thank you Mike. Please let us know if you find any other issue with the Python add-ins. You can email me directly at nahmed@esri.com

Meanwhile, could you please let us know the workflows or scenarios where you need to use wxPython?
0 Kudos
MikeHunter
Frequent Contributor
Forms like these:

[ATTACH=CONFIG]15634[/ATTACH]

Data entry forms, listboxes, buttons, etc to facilitate work flow for non-power users.  Also, I use wxPython for simple dialogs, message boxes, Yes/No/Cancel stuff and the like.  As you can see, I'm already using wxPython forms with Arcmap, but outside the app process, so I have to constantly cross process boundaries.  Inside would be easier and faster.  I could do all this with .NET, but I'm more productive with Python.

thanks
Mike
0 Kudos
CésarGarrido_Lecca
Deactivated User
Hello Mark , i have one questión ,

How i can get a feature atributte selected from the map?

Thsk to much for your help
0 Kudos