joo*_*jaa 3 python coordinates multidimensional-array win32com
当使用python和win32com自动化软件形式时,Adobe遇到了传递2d坐标数组的问题.如果看一下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))
Run Code Online (Sandbox Code Playgroud)
现在天真的假设是VB代码可以通过如下转换成python:
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] ] )
Run Code Online (Sandbox Code Playgroud)
显然,这并不容易,python发出错误说"只支持维度为1的数组".现在我知道阵列数组和二维数组之间存在差异.所以问题是我如何强制python制作一个正确的数组呢?
我尝试制作自己的VARIANT类型,但失败了.我也看过这个问题.任何人都有同样的问题,可以解决一些问题吗?
PS:
我知道使用以下方法可以避免这个问题:
pathItem = docObj.PathItems.Add()
for point in ( [0.0,0.0], [20.0,20.0] ):
pp = pathItem.PathPoints.Add()
pp.Anchor = point
Run Code Online (Sandbox Code Playgroud)
但是有类似的情况,这实际上并不起作用.无论如何,重点是编写关于移植给学生的指导方针,以便更接近原始意图.
这是一个实际使用win32com模块的替代解决方案.碰巧的是,Illustrator和Photoshop的数组类型是变种类型的单一数组.变体类型也是数组.还有其他应用程序,如solidworks,使用相同的策略.您可以使用以下代码强制win32com创建变体类型:
from win32com.client import VARIANT
from pythoncom import VT_VARIANT
def variant(data):
return VARIANT(VT_VARIANT, data)
Run Code Online (Sandbox Code Playgroud)
方便的是,人们不需要总是在任何地方键入变量,因此您可以只使用python数组并使用以下内容创建每个子元素变体:
import collections
def vararr(*data):
if ( len(data) == 1 and
isinstance(data, collections.Iterable) ):
data = data[0]
return map(variant, data)
Run Code Online (Sandbox Code Playgroud)
所以最后我的完整代码如下:
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]] ) )
Run Code Online (Sandbox Code Playgroud)
是的,这可以用comtypes完成,但这回答了我在win32com中如何做到的真正问题.除了有理由使用win32com,例如能够生成常量.所以经过很长一段时间,我终于找到了一个真正困惑我的问题的答案.希望这有助于某人.