如何为COM构建对象列表?

问题描述 投票:2回答:1

这是以前用VBA编写的真实项目。

我想将其移至Python并使用'用于带有Python的AutoCAD的ActiveX自动化脚本'方法。这是我的代码:

# -*- coding: utf-8 -*-

from pyautocad import Autocad, APoint, aDouble


acad = Autocad(False,  True)
acad.prompt("Hello, Autocad from Python\n")
print acad.doc.Name

xx = acad.model.AddCircle(APoint(0, 0),  10)
print(xx)
yy = acad.model.Add3Dpoly(aDouble([0,  0,  0,  10,  10,  10,  30,  20,  30,  0,  0,  0]))
print(yy.ObjectName)
print(yy.PlotStyleName)

# How to contruct an objectlist for AddRegion?
#regions = acad.model.AddRegion([yy])
#acad.model.AddExtrudedSolid(regions[0], 20, 0)

我的问题是,如何为AddRegion构造对象列表?也许comtypes有一些关于VARINT的话题。我真的没有关于COM的经验,等等...

python com automation activex autocad
1个回答
1
投票

使所有功能正常工作可能比看起来应该做的更多。使用python读取数据;还不错写数据,有点棘手。休闲用户/初学者;被警告要进入什么。


您可能需要什么

如果您熟悉autolisp,它将非常有帮助,因为它工作得更好(在这种情况下),文档得到了很好的记录,并且集成得更好,...并且您可能需要使用它来提取“未知/隐藏/未记录”的信息那个python没有告诉你。 (请参见vlax-vla-系列lisp函数)。

下一步,您需要从命令行中使用win32com make_py和gen_py脚本,或者您可以使用win32com.client.gencode,而大部分时间都停留在python中。

准备好以视觉方式解析非常丑陋的文本(而且我什至没有在谈论lisp =])。准备失败,并兴奋地找出原因。

其中大部分与COM变量有关。然后您会得到诸如Variant-Variant-Arrays之类的怪异东西。如果签出win32com.client.pythoncom,您会注意到所有数据类型都映射为整数。 (例如,VT_BOOL是11)。


坚韧不拔

下次尝试ModelSpace.AddCircle时,请注意获得的调试输出;所有传递给InvokeTypes的参数都是您所需要的来监视...(这是从我的Autocad注册接口的make-py输出中获取的)>

def AddLine(self, StartPoint=defaultNamedNotOptArg, EndPoint=defaultNamedNotOptArg):       
    ret = self._oleobj_.InvokeTypes(
                        1581, LCID, 1, (9, 0), ((12, 1), (12, 1)),StartPoint, EndPoint)
    if ret is not None:
        ret = Dispatch(ret, u'AddLine', '{DF524ECB-D59E-464B-89B6-D32822282778}'

这会告诉您确切要使用哪种COM类型win32com THINKS

,因此请确保至少与之匹配。

我发现实际上记录了许多输入函数并错误地调用了它们(我在AutoLisp反复学习后才学到了这一点)。上面我们看到的在外部具有值[[1581

(类似于类名,而不是真正的数据类型),然后是元组,其基本表示为[[(DISPATCH,EMPTY) :( 9, 0),然后是VT_VARIANTS:((12,1),(12,1))的数组。 COM通常期望缺少一个外部包装程序,由于某种原因,make-py无法意识到这一点。如果您经过大量的AutoLisp vlax-废话,您会发现它们是该包装的另一种包装。我相信它要么是一个VARIANT_ARRAY,要么从字面上看,是一个VARIANT-VARIANT-ARRAY(四重指针或诸如此类)。的代码是(vt_array = 8192,vt_variant = 12)。

[抱歉,我不记得具体细节,但是我相信读((12,1),(12,1))

的部分应该变成

((8192,12,((12,1) ,(12,1)))

或类似的东西。即使您确定了它应该是什么,我也不确定它们是否是快速解决方案。对于AutoCAD 2010,对我而言,这意味着要遍历不合时宜的gen_py输出,找到我真正想要的功能,并手动更改InvokeTypes()调用以匹配COM的期望。
此后一切都按预期进行。

可能的解决方法


COM很丑。如果您是python的新手,但是在AutoCAD中是半经验的(这意味着您想做一些相当繁琐的自动化操作),请远离

python-> win32com-> AutoCAD

管道。使用LISP。令我难以忍受的是,您最终将编写大量LISP测试用例和调试器来伴随python的烦恼,您不妨提交。

Ironpython和.NET

  • 我相信这个接口通常比COM更受支持

    Visual Studio Professional(2008+)
  • 我从未使用过官方的VS-Pro工具(我使用过PythonWIN和MINGW),我不确定是否提供了任何其他魔术,这些魔术会改变win32com处理AutoCAD的方式。我知道官方的AutoCAD ARX扩展在Studio项目中提供了它们的源代码。最糟糕的情况是,您将无法获得实际的文档,这将使python-AutoCAD的整个主题受到污染。
© www.soinside.com 2019 - 2024. All rights reserved.