当使用Python和win32com自动化软件的形式通过二维坐标数组的Adobe一个遇到的问题。 如果我们看一下代码的Adobe船舶的Visual Basic(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代码可能只是刚刚被如下转换它变成蟒:
from win32com.client import Dispatch
appObj = Dispatch("Illustrator.Application")
docObj = appObj.Documents.Add()
pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( [ [0.0,0.0], [20.0,20.0] ] )
显然,这不是那么容易,蟒蛇发出错误说“只有尺寸1阵列都支持”。 现在我知道,有数组的数组和二维数组之间的差异。 所以,问题是如何强制蟒蛇作出正确类型的数组?
我试图使我自己的VARIANT类型,但悲惨地失败了。 香港专业教育学院也看了ctypes的这一点。 任何人有同样的问题,并可能提供一些线索?
PS:
据我所知,这个问题可以通过使用被规避:
pathItem = docObj.PathItems.Add()
for point in ( [0.0,0.0], [20.0,20.0] ):
pp = pathItem.PathPoints.Add()
pp.Anchor = point
但也有类似的情况下,这实际上不工作。 反正点是写在移植到学生,让正在接近原意是更好的准则。
试图确定使用win32com选择区域时,我遇到了同样的问题。 我发现,使用comtypes而不是win32com访问Photoshop中解决了多维数组问题顾左右而言他。
我认为,一分维数组的问题是win32com的限制,但我可能是错的。
你可以在这里comtypes: http://sourceforge.net/projects/comtypes/
有一个关于这个问题后科技艺术家组织 ,这是值得一看通过。
这是通过使用comtypes从高科技艺术家上面链接的论坛帖子阵列的一个例子。 为路径点的实现应该是相似的。
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)
下面是实际使用win32com模块一个替代的解决方案。 碰巧插图的阵列型以及Photoshop是变体类型的一个烧毛阵列。 其中该变体类型也是一个数组。 也有像使用同样的策略SolidWorks的其他应用程序。 您可以强制win32com使下面的代码变体类型:
from win32com.client import VARIANT
from pythoncom import VT_VARIANT
def variant(data):
return VARIANT(VT_VARIANT, data)
这将是方便的是一个将不需要总是Variant类型无所不在,所以你可以只取蟒蛇阵列,使每个子元素变种:
import collections
def vararr(*data):
if ( len(data) == 1 and
isinstance(data, collections.Iterable) ):
data = data[0]
return map(variant, data)
所以最后我的完整的代码如下所示:
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,如能产生常量。 所以很长一段时间后,我终于找到一个答案,真正困惑我的问题。 希望这可以帮助别人。