[GIS] How to call arcpy.RefreshActiveView() every 5 seconds using ArcGIS Python

arcgis-desktoparcpyexcelpython

I have an Excel macro that generates random values after every 5 secs and I am reading it in ArcGIS for Desktop… to refresh the view I have to press f5 and the view gets updated. Now I want to automate it and run the loop infinitely. I found the command for refreshing the view is

arcpy.RefreshActiveView();

I want to call this function after a delay of 5 seconds.. I tried this code

import arcpy;
import time;

while True:
    arcpy.RefreshActiveView();
    time.sleep(5);

But the problem is when I run this the main thread is blocked and the program is not responding. So I tried to move it to a new thread.

import arcpy;
import time;
from threading import Thread;

def refView() :
    while True:
        arcpy.RefreshActiveView();
        time.sleep(5);

try:
    Thread(target=refView, args=()).start();
except Exception, errtxt:
    print errtxt;

This is also not working and the application becomes not responding, please let me know what I am doing wrong …

Best Answer

Threading doesn't work with most UI manipulation in Windows as UI elements have thread affinity, which is probably why the map view is failing to refresh.

I've got a Python project that does this in ArcGIS without threading on Github. It uses the Win32 event loop in the main thread to do timed calls in an add-in extension. You can also use it independently of add-ins by using the tickextension.call_layer.CallQueue class:

import tickextension.call_later

class Refresher(tickextension.call_later.CallQueue):
    def __init__(self):
        super(Refresher, self).__init__()
        self.call_later(self.refresh_view, 5.0)
    def refresh_view(self):
        arcpy.RefreshActiveView()
        # Tell self to be called later again
        self.call_later(self.refresh_view, 5.0)

refresh_object = Refresher()

# Do some work
...
# turn off timer
refresh_object.active = False
Related Question