14

The script that I'm writing repositions two data frames and sets their extents.

When doing this, it redraws the entire Active View 4 times, slowing the script substantially.

Pressing F9 or clicking the 'Pause Drawing' button before running the script disables the drawing and makes the script run much faster, but I want the script to do this automatically.

I want to disable ArcMap 10 drawing at the beginning of the script, and enable it at the end.

How do I do this?

3 Answers 3

13

I didn't see anything native in ArcPy. The easiest thing to do is probably send the F9 keystroke to the ArcMap window using the SendKeys module.

I tested with this syntax and it worked fine:

import SendKeys
# Send the keystroke for F9
SendKeys.SendKeys("{F9}")

The only caveat is that you may need to uncheck "Always run in foreground" on the General tab of the script properties. Otherwise the keystroke may get caught by the script progress window.

6
  • Thanks! I have one question though. Any computer on our network will need to be able to use this script. Is it possible to host the SendKeys module on our server so that we don't have to install it on every computer? I'm not familiar with adding new modules
    – Tanner
    Commented Sep 1, 2010 at 23:37
  • 1
    You can use PYTHONPATH to add to the default directories that Python looks in when importing modules. I've never used this so I can't offer any guidance. More info here: docs.python.org/tutorial/modules.html#the-module-search-path
    – Evan
    Commented Sep 3, 2010 at 16:41
  • Thanks. SendKeys works when I turn off 'Always run in foreground' but the problem is, a script tool has to run in the foreground if you're using arcpy.mapping.MapDocument('Current') I wonder if there's a way to do it in ArcObjects? Then again, I have never used ArcObjects
    – Tanner
    Commented Sep 17, 2010 at 15:42
  • 1
    You can change the tool itself to always run in foreground from the Script Tool properties dialog. Commented Sep 17, 2010 at 17:53
  • That link to the SendKeys module doesn't work for me. Anyone else having issues with it? Do you have another link to download that module? Commented Aug 15, 2014 at 0:05
6

I realize this question was closed long ago, but I have some old tools that this was newly a problem for and the SendKeys solution no longer seems to work, so I rolled my own solution after experimenting. It doesn't disable drawing, but creates the performance equivalent of that by disabling layers and reenabling them when done. Having the script run in the background doesn't resolve the problem (though I thought it would), so I tried turning off all of the layers - and it worked! Full speedup to the equivalent code in an empty document. So here's some code to accomplish that.

These two functions, when combined, turn off all the layers in a document, returning the saved state of the layers. Then, when your operations are done, you can turn them back on by providing that saved state to the second function. Recommended usage:

try:
    layer_state = turn_off_all_layers("CURRENT")
    # Do interesting things here
finally:  # put it in a finally block so that if your interesting code fails, your layers still get reenabled
    turn_on_layers("CURRENT", layer_state)

And the functions are below - corrections, comments, etc welcome - pretty new code so it may have some bugs, but it's been tested some.

def turn_off_all_layers(document="CURRENT"):
    """
        A speedup function for map generation in ArcMap - turns off all layers so that it doesn't try to rerender them while we're using tools (since these tools need
        to run in the foreground and background processesing didn't seem to speed it up).

        Creates a dictionary keyed on the arcpy layer value longName which contains True or False values for whether or not the layers were enabled before running this.
        Allows us to then use turn_on_layers on the same document to reenable those layers

    :param document: a map document. defaults to "CURRENT"
    :return: dict: a dictionary keyed on layer longName values with True or False values for whether the layer was enabled.
    """
    visiblity = {}

    doc = arcpy.mapping.MapDocument(document)
    for lyr in arcpy.mapping.ListLayers(doc):
        if lyr.visible is True:
            try:
                visiblity[lyr.longName] = True
                lyr.visible = False
            except NameError:
                visiblity[lyr.longName] = False  # if we have trouble setting it, then let's not mess with it later
        else:
            visiblity[lyr.longName] = False

    return visiblity


def turn_on_layers(document="CURRENT", storage_dict=None, only_change_visible=True):

    if not storage_dict:
        raise ValueError("storage_dict must be defined and set to a list of layer names with values of False or True based on whether the layer should be on or off")

    doc = arcpy.mapping.MapDocument(document)
    for lyr in arcpy.mapping.ListLayers(doc):
        if lyr.longName in storage_dict:
            if not only_change_visible or (only_change_visible is True and storage_dict[lyr.longName] is True):  # if we're only supposed to set the ones we want to make visible and it is one, or if we want to set all
                try:
                    lyr.visible = storage_dict[lyr.longName]  # set the visibility back to what we cached
                except NameError:
                    arcpy.AddWarning("Couldn't turn layer %s back on - you may need to turn it on manually" % lyr.longName)  # we couldn't turn a layer back on... too bad
0

I couldn't find a pure python method using arcpy to do this searching the internet, but I was able to find some obscure code that was able to do this, and this is what I found (and it seems to work great):

project = arcpy.mp.ArcGISProject("CURRENT")

# Pause Drawing
project.activeView.drawMode = 'NONE'

# Code

# Un-Pause Drawing
project.activeView.drawMode = 'FULL'

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.