使用占位符

占位符可以让添加内容变得更容易。如果你曾经从零开始在幻灯片上添加新的文本框,并注意到它需要多少调整才能达到你想要的效果,你就会明白为什么。占位符位于合适的位置,具有合适的字体大小、段落对齐方式、项目符号样式等。基本上,你只需点击并输入一些文本,就能得到一张幻灯片。

占位符还可以用来在幻灯片上放置富内容对象。可以将图片、表格或图表分别插入到占位符中,从而获得占位符的位置和大小,以及某些格式属性。

访问占位符

每个占位符也是形状,所以可以使用幻灯片的 shapes 来访问。但是,当查找特定的占位符时,placeholders 属性可以让事情变得更简单。

“访问已知占位符的最可靠的方法是通过它的 idx 的值。占位符的 idx 值是它继承属性的幻灯片布局占位符的整数键。因此,它在整个幻灯片的生命周期中都保持稳定,对于使用这种布局创建的任何幻灯片都是一样的。

通常很容易看一看幻灯片上的占位符,然后挑出你想要的:

>>> prs = Presentation()
>>> slide = prs.slides.add_slide(prs.slide_layouts[8])
>>> for shape in slide.placeholders:
...     print('%d %s' % (shape.placeholder_format.idx, shape.name))
...
0  Title 1
1  Picture Placeholder 2
2  Text Placeholder 3

… 然后,手里有了已知的索引,可以直接访问它:

>>> slide.placeholders[1]
<pptx.parts.slide.PicturePlaceholder object at 0x10d094590>
>>> slide.placeholders[2].name
'Text Placeholder 3'

备注

占位符集合上的项访问类似于字典而不是列表。虽然上面使用的键是整数,但查找的是 idx 值,而不是序列中的位置。如果提供的值与其中占位符的 idx 值不匹配,则会引发 KeyErroridx 值不一定是连续的。

通常,内置幻灯片布局(PowerPoint 提供的)占位符的 idx 值将在 0 到 5 之间。title 占位符将始终具有 idx 0 (如果存在的话),任何其他占位符将按照从上到下、从左到右的顺序跟随。在 PowerPoint 中,用户添加到幻灯片布局中的占位符将接收从 10 开始的 idx 值。

确定并描述占位符的特征

占位符在某些方面的行为与其他形状不同。特别是,它的 shape_type 属性的值无条件地是 MSO_SHAPE_TYPE.PLACEHOLDER 不管它是什么类型的占位符或者它包含什么类型的内容:

>>> prs = Presentation()
>>> slide = prs.slides.add_slide(prs.slide_layouts[8])
>>> for shape in slide.shapes:
...     print('%s' % shape.shape_type)
...
PLACEHOLDER (14)
PLACEHOLDER (14)
PLACEHOLDER (14)

要想了解更多,有必要检查占位符的 placeholder_format 属性内容。所有形状都有这个属性,但是在非占位符形状上访问它会引发 ValueErroris_placeholder 可以用来确定形状是否为占位符:

>>> for shape in slide.shapes:
...     if shape.is_placeholder:
...         phf = shape.placeholder_format
...         print('%d, %s' % (phf.idx, phf.type))
...
0, TITLE (1)
1, PICTURE (18)
2, BODY (2)

占位符的另一种不同行为是,它从布局占位符继承其位置和大小。如果占位符的位置和大小被更改,这个继承将被重写。

将内容插入到占位符

某些占位符类型具有插入内容的专用方法。在当前版本中, picturetablechart 占位符都有内容插入方法。文本可以插入到 titlebody 占位符中,就像文本插入到自动形状中一样。

PicturePlaceholder.insert_picture()

picture 占位符有 insert_picture() 方法

>>> prs = Presentation()
>>> slide = prs.slides.add_slide(prs.slide_layouts[8])
>>> placeholder = slide.placeholders[1]  # idx key, not position
>>> placeholder.name
'Picture Placeholder 2'
>>> placeholder.placeholder_format.type
PICTURE (18)
>>> picture = placeholder.insert_picture('my-image.png')

备注

对图片占位符的引用在其 insert_picture() 方法调用后后失效。这是因为插入图片的过程用包含图片的新 p:pic 元素替换了原始的 p:sp XML 元素。调用之后,任何使用原始占位符引用的尝试都将引发 AttributeError。新的占位符是 insert_picture() 调用的返回值,也可以使用相同的 idx 键从占位符集合中获取。

以这种方式插入的图片会按比例拉伸和裁剪,以填满整个占位符。当源图像和占位符的长宽比相同时,效果最好。如果图片在外观上比占位符高,那么它的顶部和底部将被均匀地裁剪以适应。如果它更宽,它的左右两边被均匀地裁剪。可以使用占位符上的作物属性来调整裁剪,例如 crop_bottom

TablePlaceholder.insert_table()

表格占位符有 insert_table() 方法。内置模板没有包含表占位符的布局,所以这个例子假设名为 having-table-placeholder.pptx 的演示文稿的第二个幻灯片布局上有 idx 10 的表格占位符:

>>> prs = Presentation('having-table-placeholder.pptx')
>>> slide = prs.slides.add_slide(prs.slide_layouts[1])
>>> placeholder = slide.placeholders[10]  # idx key, not position
>>> placeholder.name
'Table Placeholder 1'
>>> placeholder.placeholder_format.type
TABLE (12)
>>> graphic_frame = placeholder.insert_table(rows=2, cols=2)
>>> table = graphic_frame.table
>>> len(table.rows), len(table.columns)
(2, 2)

以这种方式插入的表格具有原始占位符的位置和宽度。它的高度与行数成正比。

像所有的富内容插入方法一样,对表格占位符的引用在其 insert_table() 方法调用之后就会失效。这是因为插入富内容的过程将原始的 p:sp XML 元素替换为包含富内容对象的新元素(本例中为 p:graphicFrame)。调用之后,任何使用原始占位符引用的尝试都将引发 AttributeError。新的占位符是 insert_table() 调用的返回值,也可以从占位符集合中使用原来的 idx 键获得,在本例中为 10。

备注

insert_table() 方法的返回值是 GraphicFrame 对象,它拥有 GraphicFrame 对象的所有属性和方法,以及那些特定于占位符的。插入的表格包含在图形框架中,可以使用 table 来获取。

ChartPlaceholder.insert_chart()

图表占位符有 insert_chart() 方法。内置到 python-pptx 中的演示模板没有包含图表占位符的布局,所以这个例子假设名为 having-chart-placeholder.pptx 的开始演示在其第二个幻灯片布局中有 idx 10 的图表占位符:

>>> from pptx.chart.data import ChartData
>>> from pptx.enum.chart import XL_CHART_TYPE

>>> prs = Presentation('having-chart-placeholder.pptx')
>>> slide = prs.slides.add_slide(prs.slide_layouts[1])

>>> placeholder = slide.placeholders[10]  # idx key, not position
>>> placeholder.name
'Chart Placeholder 9'
>>> placeholder.placeholder_format.type
CHART (12)

>>> chart_data = ChartData()
>>> chart_data.categories = ['Yes', 'No']
>>> chart_data.add_series('Series 1', (42, 24))

>>> graphic_frame = placeholder.insert_chart(XL_CHART_TYPE.PIE, chart_data)
>>> chart = graphic_frame.chart
>>> chart.chart_type
PIE (5)

以这种方式插入的图表具有原始占位符的位置和大小。

注意 insert_chart() 返回值是 PlaceholderGraphicFrame 对象,而不是图表本身。PlaceholderGraphicFrame 对象具有 GraphicFrame 对象的所有属性和方法,以及那些特定于占位符的。”插入的图表包含在图形框架中,可以使用其 chart 属性获取。

像所有富内容插入方法一样,对图表占位符的引用在其 insert_chart() 方法被调用后失效。这是因为插入富内容的过程将原始的 p:sp XML 元素替换为包含富内容对象的新元素(本例中为 p:graphicFrame)。调用之后,任何使用原始占位符引用的尝试都将引发 AttributeError。新的占位符是 insert_chart() 调用的返回值,也可以使用原始的 idx 键从占位符集合中获取,在本例中为 10。

设置幻灯片标题

几乎所有的幻灯片布局都有标题占位符,当布局被应用时,任何基于布局的幻灯片都会继承这个占位符。访问幻灯片标题是一种常见操作,它在形状树中有专门的属性:

title_placeholder = slide.shapes.title
title_placeholder.text = 'Air-speed Velocity of Unladen Swallows'