Python, ArcObjects и.AppRef: как перейти от IAppROT к IMxDocument?

Я пишу внешний скрипт Python/comtypes (в PythonWin), который должен получить ссылку на текущую сессию ArcGIS 10.0 ArcMap (через ArcObjects COM). Поскольку скрипт находится за границей приложения, я получаю ссылку на приложение через AppROT (таблица запущенных объектов). Первый фрагмент кода ниже - это основной модуль драйвера Python. В нем есть функция GetApp() для получения ссылки на приложение из AppROT. Этот код работает нормально и возвращает IApplication для одноэлементного объекта AppRef. Имеет смысл, и именно на это указывает ссылка на ArcObjects. Теперь моя главная цель - получить IMxDocument. В основном цикле я успешно попадаю на IDocument и могу напечатать заголовок. Следующая строка, однако, Query Interface, выдает ошибку - NameError: имя 'esriArcMapUI' не определено. Ошибка возникает постоянно, даже после закрытия PythonWin и повторного открытия (что вы всегда хотите попробовать, прежде чем решите, что у вас есть проблема). [Кстати, второй фрагмент кода - это функция CType() для QI, определенная и импортированная из модуля SignHelpers.py.] Итак, вот мои вопросы:

(1) На каком COM-объекте находится IDocument?
(2) Как мне перейти от моего IDocument к предполагаемому IMxDocument? Нужно ли сначала создавать новый объект MxDocument? [Сожалею. Два вопроса там.]
(3) Если мне не нужно создавать новый объект, то как мне сделать QI?

Я много работал над ArcObjects в VB6 несколько лет назад, поэтому явные QI и пространства имен в настоящее время ставят меня в тупик. Как только я смогу получить IMxDocument, я буду дома свободен. Я был бы признателен за любую помощь, которую каждый может мне дать

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

=== code:  main py module ===  

    import sys, os  
    sys.path.append('C:\GISdata\E_drive\AirportData\ATL\Scripts')

    import comtypes
    from SignHelpers import *

    def GetApp(app):  
        """Get a hook into the current session of ArcMap; \n\  
        Execute GetDesktopModules() and GetStandaloneModules() first"""  
        print "GetApp called" #@@@  
        import comtypes.gen.esriFramework as esriFramework    
        import comtypes.gen.esriArcMapUI as esriArcMapUI  
        import comtypes.gen.esriCarto as esriCarto  
        pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)  
        iCount = pAppROT.Count  
        print "appROT count = ", iCount  #@@@  
        if iCount == 0:  
            print 'No ArcGIS application currently running.  Terminating ...'  
            return None  
        for i in range(iCount):  
            pApp = pAppROT.Item(i)  #returns IApplication on AppRef  
            if pApp.Name == app:  
                print "Application:  ", pApp.Name  #@@@  
                return pApp  
        print 'No ArcMap session is running at this time.'  
        return None  


    if __name__ == "__main__":  
        #Wrap needed ArcObjects type libraries (.olb)...  

        ... code omitted ...  

        GetDesktopModules(dtOLB)    #These force comtypes to generate  
        GetStandaloneModules(saOLB) #the Python wrappers for .olb's  

        #Connect to ArcMap      
        pApp = GetApp("ArcMap")  

        pDoc = pApp.Document  #IDocument on current Document object  
        print pDoc.Title  
        pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)  #QI to IMxDocument on MxDocument  

    === code for CType() ===  
    def CType(obj, interface):  
        try:  
            newobj = obj.QueryInterface(interface)  
            return newobj  
        except:  
            return None

1 ответ

Ошибка определения объема (согласно комментариям):

import comtypes.gen.esriArcMapUI as esriArcMapUI Оператор, необходимый для определения пространства имен esriArcMapUI, выполнялся внутри функции GetApp(), поэтому пространство имен было локальным для функции.

Другие вопросы по тегам