2012-08-30 4 views
2

Я новичок в OOP и пытаюсь использовать COM-объекты (arcobjects) в Python. Программа связана с ГИС, но я не получил никаких ответов на GIS.SE, поэтому я прошу здесь. Ниже приведен фрагмент моего кода. Я застрял в конце, где получаю iFrameElement. ESRI описывает его как член/интерфейс абстрактного класса, который не может создавать объекты самостоятельно. Мне нужно передать информацию, содержащуюся в нем, в объект CoClass (MapFrame).COM-объекты (arcobjects) в Python

Любые предложения, как это сделать?

Также можно найти соглашения об именах для объектов в Python? Есть p, i как префикс, и я не уверен, откуда они взялись.

from comtypes.client import CreateObject, GetModule 
import arcpy 

def CType(obj, interface): 
    """Casts obj to interface and returns comtypes POINTER or None""" 
    try: 
     newobj = obj.QueryInterface(interface) 
     return newobj 
    except: 
     return None 

def NewObj(MyClass, MyInterface): 
    """Creates a new comtypes POINTER object where\n\ 
    MyClass is the class to be instantiated,\n\ 
    MyInterface is the interface to be assigned""" 
    from comtypes.client import CreateObject 
    try: 
     ptr = CreateObject(MyClass, interface=MyInterface) 
     return ptr 
    except: 
     return None 

esriCarto = GetModule(r"C:\Program Files (x86)\ArcGIS\Desktop10.0\com\esriCarto.olb") 
esriCartoUI = GetModule(r"C:\Program Files (x86)\ArcGIS\Desktop10.0\com\esriCartoUI.olb") 
esriMapUI = GetModule(r"C:\Program Files (x86)\ArcGIS\Desktop10.0\com\esriArcMapUI.olb") 
esriFrame = GetModule(r"C:\Program Files (x86)\ArcGIS\Desktop10.0\com\esriFramework.olb") 

arcpy.SetProduct('Arcinfo') 

pApp = NewObj(esriFrame.AppROT, esriFrame.IAppROT).Item(0) 
pDoc = pApp.Document 
pMxDoc = CType(pDoc, esriMapUI.IMxDocument) 
pLayout = pMxDoc.PageLayout 
pGraphContLayout = CType(pLayout, esriCarto.IGraphicsContainer) 
iFrameElement = pGraphContLayout.FindFrame(pMxDoc.ActiveView.FocusMap) 

Насколько я понимаю, iFrameElement представляет собой интерфейс абстрактного класса, из которого я должен наследовать атрибуты (указатель) на объект MapFrame. Как мне это сделать? Как получить объект с интерфейсом IMapGrids? Какие-либо предложения?

ответ

2

IFrameElement - это интерфейс, поэтому вы не можете создать экземпляр его как таковой. Этот интерфейс реализован в various classes, включая MapFrame, что означает (в основном), что экземпляр любого из этих объектов «ведет себя» как IFrameElement. Поэтому, если вы получите IFrameElement из IGraphicsContainer.FindFrame(), вы можете передать его чему-то еще, что ожидает IFrameElement без необходимости выяснять, каков фактический тип объекта.

Я бы предложил прочитать информацию о том, что означает Интерфейс в ООП, потому что код ESRI использует их много.

Об указании имен - нет жесткого правила & о том, как назвать ваши переменные.

По внешнему виду вашего кода p относится к объекту с отдельным типом, и я ссылаюсь на объект, определенный только интерфейсом. Но на этой ноте вызов переменной с тем же именем, что и интерфейс, на который он ссылается (кроме как с нижним регистром «i»), является плохим способом сделать что-то и приведет к путанице. (ИМО)

Edit: Чтобы ответить на ваш последний вопрос (к сожалению, я пропустил это изначально):

Если pGraphContLayout.FindFrame() возвращает объект типа MapFrame (и нет никакой гарантии, что это делаешь), то вы должны быть в состоянии просто бросить его через к IMapGrids:

pGraphContLayout = CType(pLayout, esriCarto.IGraphicsContainer) 
pFrame = pGraphContLayout.FindFrame(pMxDoc.ActiveView.FocusMap) 
pGrids = CType(pFrame, IMapGrids) 

Это звучит, как вы может быть путается абстрактными базовыми классами языка Python, которые, кажется, служат для интерфейсов ...? Эта нить полезна: Difference between abstract class and interface in Python

+0

Согласитесь со всем этим (согласно моему вопросу выше). Как новичок, мой вопрос в том, как вы передаете эту информацию (нужно увидеть маханизм, строку кода). Я знаю, как создать новый объект MapFrame (pMapFrame = NewObj (esriCarto.MapFrame, esriCarto.IMapFrame), но как наследовать информацию от IFrameElement? Большинство примеров находятся в VB или C# или C++, что не объясняет, как это сделать конкретно в Python Спасибо. – Tomek

+0

@Tomek: обновил мой оригинальный ответ. Если у вас есть объект типа MapFrame и вы хотите использовать методы из IFrameElement, вам просто нужно передать его в этот интерфейс: thisFE = CType (pMapFrame, IFrameElement) – Juffy

+0

Спасибо, миллион. Вот и все. На деле я немного смутился. Еще раз спасибо. – Tomek

Смежные вопросы