Python win32com和二维数组

2024-10-01 15:48:56 发布

您现在位置:Python中文网/ 问答频道 /正文

当使用python和win32com自动生成Adobe格式的软件时,会遇到传递二维坐标数组的问题。如果你看看Adobe为visualbasic(VB)提供的代码,它很简单。在Illustrator中绘制直线的简化示例如下:

Set appObj = CreateObject("Illustrator.Application")
Set docObj = appObj.Documents.Add

Set pathItem = docObj.PathItems.Add
    pathItem.SetEntirePath Array(Array(0.0, 0.0), Array(20.0, 20.0))

现在天真的假设是VB代码可以通过如下方式转换为python:

^{pr2}$

显然,这并不是那么容易,python会发出一个错误,说“只支持维度为1的数组”。现在我知道数组和二维数组是有区别的。所以问题是如何强制python生成正确类型的数组?在

我试着做我自己的变体,但失败得很惨。我还研究了ctypes。有谁也有同样的问题,能给我们一些启示吗?在

附言:

我知道可以通过使用以下方法来避免这个问题:

pathItem = docObj.PathItems.Add()
for point in (  [0.0,0.0], [20.0,20.0] ):
    pp = pathItem.PathPoints.Add() 
    pp.Anchor = point

但在类似的情况下,这实际上并不起作用。不管怎样,关键是要写下移植到学生的指导方针,以便尽可能接近最初的意图会更好。在


Tags: 代码add数组arrayppwin32compointadobe
2条回答

这是一个实际使用win32com模块的替代解决方案。碰巧IllustratorPhotoshop的数组类型是一个变体类型的单一数组。其中变量类型也是数组。也有其他应用程序,如solidworks,使用相同的策略。您可以使用以下代码强制win32com生成变量类型:

from win32com.client import VARIANT
from pythoncom import VT_VARIANT

def variant(data):
    return VARIANT(VT_VARIANT, data)

这样做很方便,您不必总是在任何地方键入variant,这样您就可以使用一个python数组,使每个子元素变量具有:

^{pr2}$

最后,我的完整代码如下所示:

from win32com.client import Dispatch, VARIANT
from pythoncom import VT_VARIANT
import collections


appObj = Dispatch("Illustrator.Application")  
docObj = appObj.Documents.Add()

def variant(data):
    return VARIANT(VT_VARIANT, data)

def vararr(*data):
    if (  len(data) == 1 and 
          isinstance(data, collections.Iterable) ):
        data = data[0]
    return map(variant, data)

pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( vararr( [0.0,0.0], [20.0,20.0] )  )

#or you can have a iterable of iterables
pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( vararr( [[30.0,10.0], [60.0,60.0]] )  )

是的,这可以用comtypes完成,但这回答了我在win32com中如何做到这一点的真正问题。此外,使用win32com还有一些原因,比如能够生成常量。因此,在很长时间之后,我终于找到了一个真正困扰我的问题的答案。希望这对某人有帮助。在

我在尝试使用win32com确定选择区域时遇到了同样的问题。我发现使用comtypes而不是win32com访问photoshop彻底解决了多维数组问题。在

我认为一维数组问题是win32com的局限性,但我可能错了。在

您可以在这里获得comtypes: http://sourceforge.net/projects/comtypes/

Tech Artists Org上有一篇关于这个问题的帖子,值得一看。在

下面是一个使用comtypes从上面链接的tech-artist论坛帖子中传递数组的示例。路径点的实现应该类似。在

import comtypes.client
ps_app = comtypes.client.CreateObject('Photoshop.Application') 
# makes a new 128x128 image
ps_app.Documents.Add(128, 128, 72)

# select 10x10 pixels in the upper left corner
sel_area = ((0, 0), (10, 0), (10, 10), (0, 10), (0, 0))
ps_app.ActiveDocument.Selection.Select(sel_area)

相关问题 更多 >

    热门问题