Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python win32com和二维数组_Python_Multidimensional Array_Coordinates_Win32com - Fatal编程技术网

Python win32com和二维数组

Python win32com和二维数组,python,multidimensional-array,coordinates,win32com,Python,Multidimensional Array,Coordinates,Win32com,当使用python和win32com自动化软件表单Adobe时,会遇到传递二维坐标数组的问题。如果你看一看Adobe为visual basic(VB)提供的代码,就会发现它很简单。在Illustrator中绘制线条的简化示例如下所示: Set appObj = CreateObject("Illustrator.Application") Set docObj = appObj.Documents.Add Set pathItem = docObj.PathItems.Add path

当使用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))
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] ] )
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]] )  )
现在,天真的假设是,VB代码可以通过如下方式转换为python:

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))
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] ] )
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]] )  )
显然,这并不是那么容易,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

但也有类似的情况,这实际上不起作用。无论如何,重点是编写关于向学生移植的指导原则,以便尽可能接近原始意图。

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

我相信一维数组问题是win32com的一个局限,但我可能错了

您可以在此处获取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)

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

from win32com.client import VARIANT
from pythoncom import VT_VARIANT

def variant(data):
    return VARIANT(VT_VARIANT, data)
方便的做法是,您不必总是在任何地方键入variant,因此您只需使用python数组,并使用以下内容使每个子元素都变为variant:

import collections

def vararr(*data):
    if (  len(data) == 1 and 
          isinstance(data, collections.Iterable) ):
        data = data[0]
    return map(variant, data)
最后,我的完整代码如下所示:

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))
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] ] )
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实现,但这回答了我的问题,即如何在Win32 COM中实现这一点。此外,使用win32com还有一些原因,例如能够生成常量。因此,经过很长一段时间,我终于找到了一个真正困扰我的问题的答案。希望这对某人有所帮助。

是的,这是可行的,只是我更愿意在win32com中这样做,因为默认情况下这些计算机上都会提供这种功能。哦,我想再和IT部门协商一个月吧。