python - 如何为 COM 构造对象列表?

标签 python com automation activex autocad

这是之前用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读取数据;还不错。写入数据,有点棘手。休闲用户/初学者;被警告你进入什么。

你可能需要什么

如果您熟悉 autolisp,它会大有帮助,因为它只是工作得更好(在这种情况下),记录得更好,并且集成得更好,......而且您可能需要它来榨取 python 的“未知/隐藏/未记录”信息不告诉你。 (参见 lisp 函数的 vlax- 和 vla- 系列)。

接下来你需要 win32com 命令行中的 make_py 和 gen_py 脚本,或者您可以使用 win32com.client.gencode 而主要停留在python中。

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

其中大部分与 COM 变体有关。然后你会得到一些奇怪的东西,比如 Variant-Variant-Arrays。如果您查看 win32com.client.pythoncom ,您会注意到所有数据类型都映射到整数。 (例如 VT_BOOL 为 11)。

坚韧不拔

下次您尝试 ModelSpace.AddCircle 时,请注意您获得的调试输出;
所有传递给 InvokeTypes 的参数是您需要的 注意...(这是从我的 Autocad 注册接口(interface)的 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 认为 它想要,所以请确保您至少匹配它。

我发现许多输入函数实际上被记录和调用是错误的(我在反复使用 AutoLisp 之后才知道这一点)。我们在上面看到的值为 1581 在外部(类似于类名,而不是真正的数据类型),然后是元组,基本上是 (调度,空) :(9,0),然后是 VT_VARIANTS 数组:((12,1),(12,1))。

COM 所期望的通常缺少一个外包装,并且由于某种原因 make-py 没有意识到这一点。如果你仔细阅读大量的 AutoLisp vlax-nonsense,你会注意到它们是一个额外的包装器。我相信它要么是 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
  • 我相信这个接口(interface)比一般的 COM 更受支持
  • Visual Studio 专业版 (2008+)
  • 我从未使用过官方的 VS-Pro 工具(我使用过 PythonWIN 和 MINGW),我不确定是否提供了任何额外的魔法来改变 win32com 处理 AutoCAD 的方式。我知道官方的 AutoCAD ARX 扩展在 Studio 项目中提供了它们的源代码。最坏的情况是你手头有实际的文档,这就是整个 python-AutoCAD 主题被污染的地方。
  • 关于python - 如何为 COM 构造对象列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15204971/

    相关文章:

    python - 与 Python 2 相比,Python 3 上的 Tensorflow 更慢

    c++ - 我如何为我的应用程序创建自己的实例 excel 并使用它?

    c# - _bstr_r 与 _T ("")

    在没有应用程序源代码的情况下使用 espresso 进行 Android 自动化

    testing - 使用 Appium、Opencv 和 Bitbar Akaze(图像识别)进行手机游戏自动化测试

    python - 导入错误: No module named vcs after manual install

    python - 神经网络 - 输出收敛于 0,python

    python - Pandas 数据框分组日期时间月

    visual-studio - Visual Studio导致嵌入式程序集 list 在调试时被忽略

    android - 如何为 Android 的 appium 自动化编写测试套件