我正在尝试为ArcMap创建一个“自动刷新”工具,以刷新DataFrame。我相信版本10有一个可以为此目的下载的插件..但是我们在工作中运行10.1并且没有这样的工具。
编辑 wxPython的计时器应该可以工作,但是在弧中使用wx是很棘手的。以下是代码目前的样子:
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)
你会注意到那里的PySimpleApp内容。我从Cederholm的演讲中得到了这个。我想知道我是否误解了一些事情。我应该为扩展创建一个完全独立的插件吗?然后,使用我需要的代码创建我的工具栏/栏插件?我问这个是因为我没有看到下面代码中引用的PySimpleApp,或者在启动覆盖方法中从wx导入的任何内容......我认为这是必需的/所有这一点。我非常感谢你的帮助。请告诉我您在我的代码中看到的内容。
答案 0 :(得分:3)
您不能按照您尝试的方式执行此操作,因为time.sleep
将阻止并锁定整个应用程序。 ArcGIS中的Python插件是一个非常新的东西,还有许多尚未实现的功能。其中之一是某种类型的更新或计时器事件,就像您在.NET和ArcObjects中获得的那样。您可能会想到在这种情况下使用threading.Thread和threading.Event,但与线程无关将在Python addin环境中起作用。至少我不能让它发挥作用。所以我在这种情况下所做的就是使用wxPython和Timer类。如果正确设置了插件,下面的代码将起作用。
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)
使用工具栏和按钮类制作扩展插件。覆盖扩展的startup
方法,如上所示。这将创建一个带有计时器的Frame子类的实例。然后,每当您单击工具栏上的按钮时,计时器将打开或关闭。 Timer参数以毫秒为单位,因此显示的代码每5秒刷新一次。
您可以在addins here中阅读有关使用wxPython的更多信息。特别注意MCederholm的帖子,比如print语句不起作用。
代码使用addin扩展类的startup
方法覆盖。这个方法应该在Arcmap启动时运行,但是从你的注释中可以看出这个启动方法无法在启动时运行。如果你不正确地创建你的插件,这是可能的,但在我的测试中它对我来说很好。如果你继续得到“AttributeError:'NoneType'对象没有属性'timer'”,那么改变按钮类的onClick
方法,如下所示:
def onClick(self):
if WATCHER is None:
global WATCHER
WATCHER = watcherDialog()
if not WATCHER.timer.IsRunning():
WATCHER.timer.Start(5000)
else:
WATCHER.timer.Stop()
前3行检查以确保WATCHER变量已设置为watcherDialog
的实例,但仍未设置为None
。不知道为什么你的启动方法没有运行,但希望这会为你解决问题。
答案 1 :(得分:0)
您可以使用RefreshTOC或RefreshActiveView方法。只需添加timer
即可