首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NameError由IUpdater通过pyRevit注册

NameError由IUpdater通过pyRevit注册
EN

Stack Overflow用户
提问于 2020-06-30 19:50:07
回答 1查看 211关注 0票数 1

我正在尝试实现一个动态模型更新器,作为pyRevit扩展的一部分。但是,我无法从更新程序的Execute方法中实例化类、调用函数或引用常量。

作为一个例子,让我们假设让一个按钮执行这个脚本:

代码语言:javascript
复制
from pyrevit import HOST_APP, DB
from System import Guid
from Autodesk.Revit.UI import TaskDialog

def do_thing(wall):
    TaskDialog.Show('ExampleUpdater', 'Updating {}'.format(wall.Id.IntegerValue))

class ExampleUpdater(DB.IUpdater):

    def __init__(self, addin_id):
        self.id = DB.UpdaterId(addin_id, Guid("70f3be2d-b524-4798-8baf-5b249c2f31c4"))

    def GetUpdaterId(self):
        return self.id

    def GetUpdaterName(self):
        return "Example Updater"

    def GetAdditionalInformation(self):
        return "Just an example"

    def GetChangePriority(self):
        return DB.ChangePriority.Views

    def Execute(self, data):
        doc = data.GetDocument()
        
        for id in data.GetModifiedElementIds():
            wall = doc.GetElement(id)
            try:
                do_thing(wall)

            except Exception as err:
                wall.ParametersMap["Comments"].Set("{}: {}".format(err.__class__.__name__, err))


updater = ExampleUpdater(HOST_APP.addin_id)

if DB.UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId()):
    DB.UpdaterRegistry.UnregisterUpdater(updater.GetUpdaterId())
    
DB.UpdaterRegistry.RegisterUpdater(updater)
wall_filter = DB.ElementCategoryFilter(DB.BuiltInCategory.OST_Walls)
change_type = DB.Element.GetChangeTypeAny()
DB.UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), wall_filter, change_type)

如果我移动了一个墙(当然是在单击按钮注册更新程序之后),就会引发一个异常并将其存储在wall的comments属性:NameError: name 'do_thing' is not defined中。当我试图调用最初在Python中未定义的函数(如TaskDialog.Show )时,也会引发类似的异常。

但是,如果我在RevitPythonShell中注册了相同的更新程序,它就会像预期的那样工作:

代码语言:javascript
复制
from System import Guid
from Autodesk.Revit.UI import TaskDialog

def do_thing(wall):
    TaskDialog.Show('ExampleUpdater', 'Updating {}'.format(wall.Id.IntegerValue))

class ExampleUpdater(IUpdater):

    def __init__(self, addin_id):
        self.id = UpdaterId(addin_id, Guid("c197ee15-47a9-4cf7-b12c-43b863497826"))

    def GetUpdaterId(self):
        return self.id

    def GetUpdaterName(self):
        return "Example Updater"

    def GetAdditionalInformation(self):
        return "Just an example"

    def GetChangePriority(self):
        return ChangePriority.Views

    def Execute(self, data):
        doc = data.GetDocument()
        
        for id in data.GetModifiedElementIds():
            wall = doc.GetElement(id)
            try:
                do_thing(wall)

            except Exception as err:
                wall.ParametersMap["Comments"].Set("{}: {}".format(err.__class__.__name__, err))


updater = ExampleUpdater(__revit__.Application.ActiveAddInId)

if UpdaterRegistry.IsUpdaterRegistered(updater.GetUpdaterId()):
    UpdaterRegistry.UnregisterUpdater(updater.GetUpdaterId())
    
UpdaterRegistry.RegisterUpdater(updater)
wall_filter = ElementCategoryFilter(BuiltInCategory.OST_Walls)
change_type = Element.GetChangeTypeAny()
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), wall_filter, change_type)

允许更新程序在RevitPythonShell中工作而不是在pyRevit中工作的两个环境之间有什么区别?

修订2019年,pyRevit 4.7.4,IronPython 2.7.7

EN

回答 1

Stack Overflow用户

发布于 2020-07-02 18:08:45

基于@Callum的建议,我能够通过保存对更新程序的__init__方法中所需导入资源的引用来解决这个问题。我的示例更新程序现在如下所示:

代码语言:javascript
复制
from pyrevit import HOST_APP, DB
from System import Guid
from Autodesk.Revit.UI import TaskDialog

class ExampleUpdater(DB.IUpdater):

    def __init__(self, addin_id):
        self.id = DB.UpdaterId(addin_id, Guid("70f3be2d-b524-4798-8baf-5b249c2f31c4"))
        self.TaskDialog = TaskDialog

    def GetUpdaterId(self):
        return self.id

    def GetUpdaterName(self):
        return "Example Updater"

    def GetAdditionalInformation(self):
        return "Just an example"

    def GetChangePriority(self):
        return DB.ChangePriority.Views

    def Execute(self, data):
        doc = data.GetDocument()
        
        for id in data.GetModifiedElementIds():
            wall = doc.GetElement(id)
            try:
                self.do_thing(wall)

            except Exception as err:
                wall.ParametersMap["Comments"].Set("{}: {}".format(err.__class__.__name__, err))
    
    def do_thing(self, wall):
        self.TaskDialog.Show('ExampleUpdater', 'Updating {}'.format(wall.Id.IntegerValue))

仅仅将do_thing作为ExampleUpdater的一种方法是不够的,保存对do_thing函数的引用(即通过在__init__中添加self.do_thing = do_thing )也是行不通的。在这两种情况下,更新者都提出了一个NameError,上面写着global name 'TaskDialog' is not defined

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62665168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档