Adding and configuring visual elements including text boxes, images, autoshapes, connectors, and containers. Covers shape properties, positioning, styling, and shape-specific operations.
Add and manage shapes within slides, layouts, and masters using shape collections.
class SlideShapes:
"""Collection of shapes on a slide."""
def add_textbox(self, left: int, top: int, width: int, height: int) -> Shape:
"""
Add a text box shape.
Parameters:
- left, top: Position in EMU from slide origin
- width, height: Dimensions in EMU
Returns:
Shape object containing the text box
"""
def add_picture(self, image_file, left: int, top: int, width: int = None, height: int = None) -> Picture:
"""
Add a picture shape.
Parameters:
- image_file: str path or file-like object with image data
- left, top: Position in EMU
- width, height: Dimensions in EMU (maintains aspect ratio if only one specified)
Returns:
Picture object
"""
def add_shape(self, autoshape_type: MSO_AUTO_SHAPE_TYPE, left: int, top: int, width: int, height: int) -> Shape:
"""
Add an autoshape (rectangle, oval, arrow, etc.).
Parameters:
- autoshape_type: MSO_AUTO_SHAPE_TYPE enum value
- left, top, width, height: Position and dimensions in EMU
Returns:
Shape object
"""
def add_connector(self, connector_type: MSO_CONNECTOR_TYPE, begin_x: int, begin_y: int, end_x: int, end_y: int) -> Connector:
"""
Add a connector line between two points.
Parameters:
- connector_type: MSO_CONNECTOR_TYPE (STRAIGHT, ELBOW, CURVE)
- begin_x, begin_y: Start point in EMU
- end_x, end_y: End point in EMU
Returns:
Connector object
"""
def add_table(self, rows: int, cols: int, left: int, top: int, width: int, height: int) -> GraphicFrame:
"""
Add a table.
Parameters:
- rows, cols: Table dimensions
- left, top, width, height: Position and size in EMU
Returns:
GraphicFrame containing Table object
"""
def add_chart(self, chart_type: XL_CHART_TYPE, x: int, y: int, cx: int, cy: int, chart_data) -> GraphicFrame:
"""
Add a chart.
Parameters:
- chart_type: XL_CHART_TYPE enum value
- x, y: Position in EMU
- cx, cy: Dimensions in EMU
- chart_data: ChartData object with series data
Returns:
GraphicFrame containing Chart object
"""
def add_group_shape(self) -> GroupShape:
"""Add an empty group shape container."""
@property
def title(self) -> Shape:
"""Title shape if present, None otherwise."""
@property
def placeholders(self) -> SlidePlaceholders:
"""Placeholder shapes on this slide."""
def __getitem__(self, index: int) -> BaseShape:
"""Get shape by index."""
def __len__(self) -> int:
"""Number of shapes."""
def __iter__(self):
"""Iterate over shapes."""Common properties and operations available on all shapes.
class BaseShape:
"""Base class for all shapes with common properties."""
@property
def name(self) -> str:
"""Shape name (editable)."""
@name.setter
def name(self, name: str):
"""Set shape name."""
@property
def shape_id(self) -> int:
"""Unique shape identifier within slide."""
@property
def shape_type(self) -> MSO_SHAPE_TYPE:
"""Type of shape (AUTO_SHAPE, PICTURE, TABLE, etc.)."""
@property
def left(self) -> int:
"""Left edge position in EMU."""
@left.setter
def left(self, left: int):
"""Set left position."""
@property
def top(self) -> int:
"""Top edge position in EMU."""
@top.setter
def top(self, top: int):
"""Set top position."""
@property
def width(self) -> int:
"""Shape width in EMU."""
@width.setter
def width(self, width: int):
"""Set shape width."""
@property
def height(self) -> int:
"""Shape height in EMU."""
@height.setter
def height(self, height: int):
"""Set shape height."""
@property
def rotation(self) -> float:
"""Shape rotation in degrees."""
@rotation.setter
def rotation(self, rotation: float):
"""Set rotation in degrees."""
@property
def fill(self) -> FillFormat:
"""Shape fill formatting."""
@property
def line(self) -> LineFormat:
"""Shape line/border formatting."""
@property
def shadow(self) -> ShadowFormat:
"""Shape shadow formatting."""
@property
def click_action(self) -> ActionSetting:
"""Click action settings."""Work with predefined shapes like rectangles, ovals, arrows, and more complex forms.
class Shape(BaseShape):
"""AutoShape object for rectangles, ovals, and other predefined shapes."""
@property
def auto_shape_type(self) -> MSO_AUTO_SHAPE_TYPE:
"""Specific autoshape type."""
@property
def text(self) -> str:
"""Text content of shape."""
@text.setter
def text(self, text: str):
"""Set text content."""
@property
def text_frame(self) -> TextFrame:
"""Text frame for rich text formatting."""
@property
def has_text_frame(self) -> bool:
"""True if shape can contain text."""
@property
def adjustments(self) -> Adjustments:
"""Shape-specific adjustment values."""Add and configure image shapes with various image formats and sizing options.
class Picture(BaseShape):
"""Picture shape containing an image."""
@property
def image(self) -> Image:
"""Image object with format details."""
@property
def crop_left(self) -> float:
"""Left crop as fraction (0.0-1.0)."""
@crop_left.setter
def crop_left(self, crop: float):
"""Set left crop fraction."""
@property
def crop_top(self) -> float:
"""Top crop as fraction."""
@crop_top.setter
def crop_top(self, crop: float):
"""Set top crop fraction."""
@property
def crop_right(self) -> float:
"""Right crop as fraction."""
@crop_right.setter
def crop_right(self, crop: float):
"""Set right crop fraction."""
@property
def crop_bottom(self) -> float:
"""Bottom crop as fraction."""
@crop_bottom.setter
def crop_bottom(self, crop: float):
"""Set bottom crop fraction."""
class Image:
"""Image data and properties."""
@property
def blob(self) -> bytes:
"""Raw image bytes."""
@property
def content_type(self) -> str:
"""MIME type (image/jpeg, image/png, etc.)."""
@property
def ext(self) -> str:
"""File extension (.jpg, .png, etc.)."""
@property
def filename(self) -> str:
"""Filename as stored in package."""
@property
def sha1(self) -> str:
"""SHA1 hash of image bytes."""Create and configure line connectors between shapes or points.
class Connector(BaseShape):
"""Line connector shape."""
@property
def begin_x(self) -> int:
"""Start point X coordinate in EMU."""
@begin_x.setter
def begin_x(self, x: int):
"""Set start X coordinate."""
@property
def begin_y(self) -> int:
"""Start point Y coordinate in EMU."""
@begin_y.setter
def begin_y(self, y: int):
"""Set start Y coordinate."""
@property
def end_x(self) -> int:
"""End point X coordinate in EMU."""
@end_x.setter
def end_x(self, x: int):
"""Set end X coordinate."""
@property
def end_y(self) -> int:
"""End point Y coordinate in EMU."""
@end_y.setter
def end_y(self, y: int):
"""Set end Y coordinate."""
@property
def connector_type(self) -> MSO_CONNECTOR_TYPE:
"""Connector type (STRAIGHT, ELBOW, CURVE)."""Create and manage grouped shapes that act as a single unit.
class GroupShape(BaseShape):
"""Container for grouped shapes."""
@property
def shapes(self) -> GroupShapes:
"""Collection of shapes in this group."""
class GroupShapes:
"""Collection of shapes within a group."""
def add_textbox(self, left: int, top: int, width: int, height: int) -> Shape:
"""Add text box to group."""
def add_picture(self, image_file, left: int, top: int, width: int = None, height: int = None) -> Picture:
"""Add picture to group."""
def add_shape(self, autoshape_type: MSO_AUTO_SHAPE_TYPE, left: int, top: int, width: int, height: int) -> Shape:
"""Add autoshape to group."""
def __getitem__(self, index: int) -> BaseShape:
"""Get shape by index."""
def __len__(self) -> int:
"""Number of shapes in group."""Container shapes for tables, charts, and other embedded objects.
class GraphicFrame(BaseShape):
"""Container for tables, charts, and embedded objects."""
@property
def has_table(self) -> bool:
"""True if contains a table."""
@property
def has_chart(self) -> bool:
"""True if contains a chart."""
@property
def table(self) -> Table:
"""Table object if present."""
@property
def chart(self) -> Chart:
"""Chart object if present."""Usage examples:
from pptx import Presentation
from pptx.util import Inches
from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE, MSO_CONNECTOR_TYPE
from pptx.dml.color import RGBColor
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6]) # Blank layout
# Add text box
left = top = Inches(1)
width = height = Inches(3)
textbox = slide.shapes.add_textbox(left, top, width, height)
textbox.text = "This is a text box"
# Add rectangle with formatting
rect = slide.shapes.add_shape(
MSO_AUTO_SHAPE_TYPE.RECTANGLE,
Inches(1), Inches(4), Inches(2), Inches(1)
)
rect.text = "Rectangle"
rect.fill.solid()
rect.fill.fore_color.rgb = RGBColor(255, 0, 0) # Red fill
rect.line.color.rgb = RGBColor(0, 0, 255) # Blue border
# Add picture
img_path = 'image.jpg'
pic = slide.shapes.add_picture(img_path, Inches(5), Inches(1), Inches(2))
# Add connector line
connector = slide.shapes.add_connector(
MSO_CONNECTOR_TYPE.STRAIGHT,
Inches(3), Inches(4.5), # Start point
Inches(5), Inches(2) # End point
)
connector.line.color.rgb = RGBColor(0, 255, 0) # Green line
# Work with shape properties
for shape in slide.shapes:
print(f"Shape: {shape.name}, Type: {shape.shape_type}")
print(f"Position: ({shape.left}, {shape.top})")
print(f"Size: {shape.width} x {shape.height}")
prs.save('shapes-example.pptx')from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE, MSO_SHAPE_TYPE, MSO_CONNECTOR_TYPE
# Common autoshape types
MSO_AUTO_SHAPE_TYPE.RECTANGLE
MSO_AUTO_SHAPE_TYPE.OVAL
MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE
MSO_AUTO_SHAPE_TYPE.TRIANGLE
MSO_AUTO_SHAPE_TYPE.DIAMOND
MSO_AUTO_SHAPE_TYPE.RIGHT_ARROW
MSO_AUTO_SHAPE_TYPE.LEFT_ARROW
MSO_AUTO_SHAPE_TYPE.UP_ARROW
MSO_AUTO_SHAPE_TYPE.DOWN_ARROW
MSO_AUTO_SHAPE_TYPE.STAR_5_POINT
MSO_AUTO_SHAPE_TYPE.HEART
MSO_AUTO_SHAPE_TYPE.SMILEY_FACE
# Shape type identification
MSO_SHAPE_TYPE.AUTO_SHAPE # AutoShape
MSO_SHAPE_TYPE.PICTURE # Picture
MSO_SHAPE_TYPE.TABLE # Table
MSO_SHAPE_TYPE.CHART # Chart
MSO_SHAPE_TYPE.GROUP # Group
MSO_SHAPE_TYPE.CONNECTOR # Connector
MSO_SHAPE_TYPE.TEXT_BOX # Text box
MSO_SHAPE_TYPE.PLACEHOLDER # Placeholder
MSO_SHAPE_TYPE.MEDIA # Video/audio
# Connector types
MSO_CONNECTOR_TYPE.STRAIGHT # Straight line
MSO_CONNECTOR_TYPE.ELBOW # Right-angle connector
MSO_CONNECTOR_TYPE.CURVE # Curved connector