RevitPythonShell - IronPython.Runtime.UnboundNameException: глобальное имя 'doc' не определено - PullRequest
1 голос
/ 25 июня 2019

я пишу свою первую кнопку в RPS, но кажется, что файл инициализации не читается при запуске или при нажатии кнопки. это ошибка, которую я получаю, когда пытаюсь следовать учебным пособиям на YouTube.

IronPython.Runtime.UnboundNameException: global name 'doc' is not defined

Я также получал аналогичную ошибку для сборщика фильтрованных элементов, пока не скопировал и не вставил импорт из сценария инициализации в мой файл кнопки.

Кто-нибудь имел какие-либо проблемы или нашел какие-либо решения для этого?

вот часть моего кода, где он выдает ошибку:

import os
import csv
import rpw
from rpw.ui.forms import Console
from rpw.ui.forms import SelectFromList

desktop = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
filepath = os.path.join(desktop, 'RevisionClouds.csv')

cl = FilteredElementCollector(doc)
cl.OfCategory(BuiltInCategory.OST_RevisionClouds)
cl.WhereElementIsNotElementType()

Я в Revit 2019 с RPS под управлением Python 2.7.7

Вот мой файл init.py. я добавил еще пару импортов, и он отлично работает с RPS и его консолью. но когда дело доходит до формы кнопки pyRevit, в doc происходит ошибка, когда она уже определена в скрипте инициализации.

init.py

# these commands get executed in the current scope
# of each new shell (but not for canned commands)

import clr
import rpw
from rpw import revit, db, ui, DB, UI

clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
clr.AddReferenceByPartialName('PresentationCore')
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName('System')
clr.AddReferenceByPartialName('System.Windows.Forms')

from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Architecture import *
from Autodesk.Revit.DB.Analysis import *
from Autodesk.Revit.UI import *

from Autodesk.Revit import DB
from Autodesk.Revit import UI


uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document

from Autodesk.Revit.UI import TaskDialog
from Autodesk.Revit.UI import UIApplication


def alert(msg):
    TaskDialog.Show('RevitPythonShell', msg)


def quit():
    __window__.Close()
exit = quit


def get_selected_elements(doc):
    """API change in Revit 2016 makes old method throw an error"""
    try:
        # Revit 2016
        return [doc.GetElement(id)
                for id in __revit__.ActiveUIDocument.Selection.GetElementIds()]
    except:
        # old method
        return list(__revit__.ActiveUIDocument.Selection.Elements)
selection = get_selected_elements(doc)
# convenience variable for first element in selection
if len(selection):
    s0 = selection[0]

#------------------------------------------------------------------------------
import clr
from Autodesk.Revit.DB import ElementSet, ElementId

class RevitLookup(object):
    def __init__(self, uiApplication):
        '''
        for RevitSnoop to function properly, it needs to be instantiated
        with a reference to the Revit Application object.
        '''
        # find the RevitLookup plugin
        try:
            rlapp = [app for app in uiApplication.LoadedApplications
                     if app.GetType().Namespace == 'RevitLookup'
                     and app.GetType().Name == 'App'][0]
        except IndexError:
            self.RevitLookup = None
            return
        # tell IronPython about the assembly of the RevitLookup plugin
        clr.AddReference(rlapp.GetType().Assembly)
        import RevitLookup
        self.RevitLookup = RevitLookup
        # See note in CollectorExt.cs in the RevitLookup source:
        self.RevitLookup.Snoop.CollectorExts.CollectorExt.m_app = uiApplication
        self.revit = uiApplication

    def lookup(self, element):
        if not self.RevitLookup:
            print 'RevitLookup not installed. Visit https://github.com/jeremytammik/RevitLookup to install.'
            return
        if isinstance(element, int):
            element = self.revit.ActiveUIDocument.Document.GetElement(ElementId(element))
        if isinstance(element, ElementId):
            element = self.revit.ActiveUIDocument.Document.GetElement(element)
        if isinstance(element, list):
            elementSet = ElementSet()
            for e in element:
                elementSet.Insert(e)
            element = elementSet
        form = self.RevitLookup.Snoop.Forms.Objects(element)
        form.ShowDialog()
_revitlookup = RevitLookup(__revit__)
def lookup(element):
    _revitlookup.lookup(element)

#------------------------------------------------------------------------------

# a fix for the __window__.Close() bug introduced with the non-modal console
class WindowWrapper(object):
    def __init__(self, win):
        self.win = win

    def Close(self):
        self.win.Dispatcher.Invoke(lambda *_: self.win.Close())

    def __getattr__(self, name):
        return getattr(self.win, name)
__window__ = WindowWrapper(__window__)

любая помощь приветствуется!

1 Ответ

3 голосов
/ 26 июня 2019

По моему опыту, файл 'init' хорош только для использования консоли на лету.При развертывании сценария на кнопку (также называемую «консервированная команда») необходимо включить все предварительные определения из файла «init».

Это объясняет, почему doc работает нормально, когдавы запускаете скрипт из консоли, но не определяется при развертывании на кнопку ленты.

То же самое относится к первым строкам файла инициализации:

# these commands get executed in the current scope
# of each new shell (but not for canned commands)

Попробуйте добавить всеimport и clr.AddReference строк кода в развернутом файле кнопок и посмотрите, что произойдет

...