2

我是 OOP 的新手,并试图在 Python 中使用 COM 对象(arcobjects)。程序与 GIS 相关,但我在 GIS.SE 上没有得到任何答案,所以我在这里问。下面是我的一段代码。我被困在收到 iFrameElement 的最后。ESRI 将其描述为抽象类的成员/接口,它本身不能创建对象。我需要将其中包含的信息传递给其 CoClass(MapFrame)中的对象。

任何建议如何做到这一点?

另外,我在哪里可以找到 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 接口获取对象?有什么建议么?

4

1 回答 1

2

IFrameElement 是一个接口,因此您不能创建它本身的实例。该接口由包括 MapFrame 在内的各种类实现,这意味着(在基本术语中)任何这些对象的实例“行为”类似于 IFrameElement。因此,如果您从 IGraphicsContainer.FindFrame() 获得 IFrameElement,则可以将其传递给其他需要 IFrameElement 的东西,而无需找出对象的实际类型。

我建议阅读一下接口在 OOP 中的含义,因为 ESRI 的代码经常使用它们

关于命名约定 - 关于变量的命名没有硬性规定。

从您的代码看起来, p 指的是具有不同类型的对象,而 i 指的是仅由接口定义的对象。但是请注意,以与其引用的接口相同的名称调用变量(小写“i”除外)是一种不好的做事方式,并且会导致混乱。(海事组织)

编辑: 回答你的最后一个问题(对不起,我最初错过了):

如果 pGraphContLayout.FindFrame() 返回 MapFrame 类型的对象(并且不能保证确实如此),那么您应该能够简单地将其转换为 IMapGrids:

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

听起来您可能对 Python 的抽象基类感到困惑,它们似乎服务于接口的目的......?这个线程很有用:Python中抽象类和接口的区别

于 2012-08-30T07:36:41.860 回答