Finding them is fairly easy; something roughly like this should do the trick:
for placeholder in slide.shapes.placeholders:
if placeholder.has_text_frame and placeholder.text_frame.text == "":
print("found one %s" % placeholder)
Deleting it is harder, because there is no direct API support for deleting shapes. However, in this simple case of text placeholders, this should work:
sp = placeholder._sp
sp.getparent().remove(sp)
The ._sp
attribute is the lxml
etree._Element
object representing the actual shape XML element (a placeholder <p:sp>
element in this case). .getparent()
and .remove()
are methods on etree._Element
and calling these manipulates the underlying XML directly. This can be dangerous, like if you tried this with a chart shape you'd probably get a repair error when you tried to load the presentation, but in this case it's safe enough.