Reputation: 1315
I am trying to create an "auto refresh" tool for ArcMap, to refresh the DataFrame. I believe version 10 had an add-on you could download for this purpose.. however we are running 10.1 at work and there is no such tool.
EDIT wxPython's timer should work, however using wx in arc is tricky. Here's what the code looks like currently:
import arcpy
import pythonaddins
import os
import sys
sMyPath = os.path.dirname(__file__)
sys.path.insert(0, sMyPath)
WATCHER = None
class WxExtensionClass(object):
"""Implementation for Refresher_addin.extension (Extension)"""
_wxApp = None
def __init__(self):
# For performance considerations, please remove all unused methods in this class.
self.enabled = True
def startup(self):
from wx import PySimpleApp
self._wxApp = PySimpleApp()
self._wxApp.MainLoop()
global WATCHER
WATCHER = watcherDialog()
class RefreshButton(object):
"""Implementation for Refresher_addin.button (Button)"""
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
if not WATCHER.timer.IsRunning():
WATCHER.timer.Start(5000)
else:
WATCHER.timer.Stop()
class watcherDialog(wx.Frame):
'''Frame subclass, just used as a timer event.'''
def __init__(self):
wx.Frame.__init__(self, None, -1, "timer_event")
#set up timer
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
def onTimer(self, event):
localtime = time.asctime( time.localtime(time.time()) )
print "Refresh at :", localtime
arcpy.RefreshActiveView()
app = wx.App(False)
You will notice the PySimpleApp stuff in there. I got that from the Cederholm's presentation. I am wondering if I am misunderstanding something though. Should I create an entirely separate addin for the extension? THEN, create my toolbar/bar addin with the code I need? I ask this because I don't see the PySimpleApp referenced in your code below, or any importing from wx in the startup override method either... which I thought was required/the point of all this. I do appreciate your help. Please let me know what you see in my code.
Upvotes: 1
Views: 2319
Reputation: 4304
You can't do this the way you are trying, because time.sleep
will block and lock up the entire application. Python addins in ArcGIS is pretty new stuff, and there's a lot of functionality that hasn't been implemented yet. One of these is some kind of update or timer event like you get in .NET and ArcObjects. You might think of using threading.Thread and threading.Event in a case like this, but nothing to do with threads will work in the Python addin environment. At least I can't get it to work. So what I've done in situations like this is use wxPython and the Timer class. The code below will work if the addin is set up correctly.
import time
import os, sys
import wx
import arcpy
mp = os.path.dirname(__file__)
sys.path.append(mp)
WATCHER = None
class LibLoader1(object):
"""Extension Implementation"""
def __init__(self):
self.enabled = True
def startup(self):
global WATCHER
WATCHER = watcherDialog()
class ButtonClass5(object):
"""Button Implementation"""
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
if not WATCHER.timer.IsRunning():
WATCHER.timer.Start(5000)
else:
WATCHER.timer.Stop()
class watcherDialog(wx.Frame):
'''Frame subclass, just used as a timer event.'''
def __init__(self):
wx.Frame.__init__(self, None, -1, "timer_event")
#set up timer
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
def onTimer(self, event):
localtime = time.asctime( time.localtime(time.time()) )
print "Refresh at :", localtime
arcpy.RefreshActiveView()
app = wx.App(False)
Make an extension addin, with a toolbar and a button class. Override the startup
method of the extension as shown above. That will create an instance of a Frame subclass with a timer. Then, whenever you click the button on the toolbar, the timer will toggle on or off. The Timer argument is in milliseconds, so the code as shown will refresh every 5 seconds.
You can read more about using wxPython in addins here. Pay particular attention to MCederholm's posts, like about the print statement not working.
The code uses a startup
method override of the addin extension class. This method is supposed to run when Arcmap starts, but it seems from your comments that this startup method is failing to run on startup. That's possible if you don't create your addin just right, but it works fine for me in my tests. If you continue to get "AttributeError: 'NoneType' object has no attribute 'timer'", then change the onClick
method of your button class like so:
def onClick(self):
if WATCHER is None:
global WATCHER
WATCHER = watcherDialog()
if not WATCHER.timer.IsRunning():
WATCHER.timer.Start(5000)
else:
WATCHER.timer.Stop()
The first 3 lines check to make sure that the WATCHER variable has been set to an instance of watcherDialog
and is not still set to None
. Don't know why your startup method is not running, but hopefully this will fix things for you.
Upvotes: 3
Reputation: 28573
You can use either the RefreshTOC or RefreshActiveView Method. Just add a timer
Upvotes: 0