首页 > 解决方案 > 除了默认的两个之外,如何使用 python-pptx 为形状添加额外的渐变填充停止

问题描述

我有一个形状,可以更改形状以使用渐变填充。如果它从以前开始有比默认两个更多的渐变停止,我可以解析它们,更改它们,然后删除它们。但是,我找不到如何添加额外的渐变停止。这就是我想要的。该文档非常正确地指出三个梯度停止是一种常见的需求。

我找到了“gradient_stops._gsLst”,但不知道添加新渐变停止的正确方法。

我尝试使用 gradient_stops.append(),它给了我一个关于预期内容的明确提示(一个 lxml.etree._Element)。但我找不到任何描述创建这样一个元素的正确方法的东西。我希望解决方案可以提供下面提到的“一些新的 GradientStop 元素”:

shape.fill.gradient_stops._gsLst.append("some new GradientStop Element")

尝试复制现有的渐变停止元素之一感觉像是在做太多的实验……

标签: python-3.xpython-pptx

解决方案


好吧,正如您所发现的,目前还没有 API 支持。但是,渐变停止元素 ( <a:gs>) 被定义为子元素,这意味着可以通过调用该对象OneOrMore将新元素添加到CT_GradientStopList对象 ( ) 中的元素的末尾。<a:gsLst>.add_gs()

所以像这样的事情会沿着正确的方向做一些事情:

>>> len(gradient_stops)
2
>>> gsLst = gradient_stops._gsLst
>>> gsLst.add_gs()
<CT_GradientStop object ... or something like that>
>>> len(gradient_stops)
3
new_gradient_stop = gradient_stops[-1]

问题是它是否会是一个有效的梯度停止元素,或者它是否会触发修复错误;我敢打赌它不会被填充到足够的数量,并且没有简单的方法可以使用 API 添加子元素。

也许更好的方法是从 XML 中解析它:

from pptx.oxml import parse_xml
from pptx.oxml.ns import nsdecls

new_gs = parse_xml(
    '<a:gs pos="0" %s>\n'
    '  <a:schemeClr val="accent1">\n'
    '    <a:tint val="100000"/>\n'
    '    <a:shade val="100000"/>\n'
    '    <a:satMod val="130000"/>\n'
    "  </a:schemeClr>\n"
    "</a:gs>\n" % nsdecls("a")
)
gradient_stops._gsLst.append(new_gs)

这与在已经存在的站点之一上进行深度复制大致相同,只是您可以指定颜色类型,就像a:srgbClr您不想使用主题颜色一样。但是,如果你知道你拥有的那个和你想要的一样,只是需要一个不同的位置和一些颜色调整或其他什么,那么 deepcopy 方法可能更适合。

from copy import deepcopy

gsLst = gradient_stops._gsLst
new_gs = deepcopy(gsLst[0])
gsLst.append(new_gs)
new_gradient_stop = gradient_stops[-1]

我确实模糊地记得头寸严格增加很重要,我认为它忽略了任何不超过前一个止损的东西,所以最好把它放在你的脑海里。


推荐阅读