使用Python在ArcGIS中自动刷新

时间:2013-05-11 20:13:17

标签: python arcgis

我正在尝试为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导入的任何内容......我认为这是必需的/所有这一点。我非常感谢你的帮助。请告诉我您在我的代码中看到的内容。

2 个答案:

答案 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)

您可以使用RefreshTOCRefreshActiveView方法。只需添加timer

即可