The .top
and .left
attributes of a shape represent the distance from the top, left corner of the slide to the top, left corner of the shape. Your idea that shape position is relative to the shape center is mistaken.
If you have text bleeding out of the left side of your shape, I would start by checking the Paragraph.alignment
setting for each paragraph in the shape text-frame:
from pptx.enum.text import PP_ALIGN
for paragraph in shape.text_frame.paragraphs:
paragraph.alignment = PP_ALIGN.LEFT
If a paragraph is aligned right, the text will grow to the left.
Another factor that can be relevant to this behavior is the TextFrame.word_wrap
setting. If word-wrap is turned off, text can bleed outside the horizontal extents of the shape.
shape.text_frame.word_wrap = True
Finally, the TextFrame.auto_size
behaviors of a shape can cause relocation of the shape, in particular, when the "Resize shape to fit text" option is selected, one or more of the size or position attributes are changed to comply. Note that this setting can interact with the paragraph alignment setting when choosing which side to "stretch" the shape to fit its text.
from pptx.enum.text import MSO_AUTO_SIZE
shape.text_frame.auto_size = MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT
You may need to experiment to find the combination that gives the behavior you want. I would say the safest place to start is this:
from pptx.enum.text import MSO_AUTO_SIZE
from pptx.enum.text import PP_ALIGN
shape = slide.shapes.add_textbox(Inches(1), top, width, height)
text_frame = shape.text_frame
text_frame.text = 'Text I want to appear in text-box'
text_frame.auto_size = MSO_AUTO_SIZE.NONE
text_frame.word_wrap = False
for paragraph in text_frame.paragraphs:
paragraph.alignment = PP_ALIGN.LEFT
Also note the behavior around auto-size can be subtly different on LibreOffice than it is on Microsoft PowerPoint. That will not be the case in the "safe" option above, but something to keep in mind.