让一切正常工作可能比看起来应该做的要多。使用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 的所有参数都是您需要注意的......(这是从我的 make-py 输出中获取的 Autocad 注册接口
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}'
这会准确告诉您win32com 认为它想要哪些 COM 类型,因此请确保您至少匹配该类型。
我发现许多输入函数实际上被记录和调用是错误的(我在多次使用 AutoLisp 后才知道这一点)。我们在上面看到的外部值为1581(类似于类名,而不是真正的数据类型),然后是基本上表示(DISPATCH, EMPTY) :(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
- Visual Studio 专业版 (2008+)
- 我从未使用过官方的 VS-Pro 工具(我使用过 PythonWIN 和 MINGW),我不确定是否提供了任何额外的魔法来改变 win32com 处理 AutoCAD 的方式。我知道官方的 AutoCAD ARX 扩展在 Studio 项目中提供了它们的源代码。最坏的情况是你手头有实际的文档,这就是整个 python-AutoCAD 主题被污染的地方。