Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shape: set z-order of shape in slide #49

Open
scanny opened this issue Oct 7, 2013 · 15 comments
Open

shape: set z-order of shape in slide #49

scanny opened this issue Oct 7, 2013 · 15 comments
Labels
Milestone

Comments

@scanny
Copy link
Owner

scanny commented Oct 7, 2013

No description provided.

@scanny scanny added shape and removed feature labels Jun 15, 2014
@scanny scanny modified the milestones: v0.4.0, Shortlist Nov 16, 2014
@NotSqrt
Copy link

NotSqrt commented Aug 20, 2015

@scanny Any pointers as to where to look in the code for something like this ?

@scanny
Copy link
Owner Author

scanny commented Sep 1, 2015

The z-order of shapes on a slide is determined solely by their document order in the slide part (e.g. slide1.xml). So the general gist would be to re-order that sequence of elements. The shapes in a slide are contained in the slide's "shape tree", a <p:spTree> element with the same syntax as the group shape, just the different name. The object I expect you'll want to look at first is pptx.shapes.shapetree.SlideShapeTree and its parent BaseShapeTree, which is what you get from slide.shapes. The _spTree attribute on that object gives you the lxml object for the <p:spTree> element, which would allow you to reorder shapes.

If you see how far you can get with that, feel free to ask more questions about the finer points, as needed :)

@NotSqrt
Copy link

NotSqrt commented Sep 2, 2015

Thanks @scanny
We ended up using shapes._spTree.remove and shapes._spTree.insert to swap elements, like you said!

@scanny
Copy link
Owner Author

scanny commented Sep 2, 2015

If you can post the operative bit of the code you developed, that would be a help to others who arrive here on search. Glad you got it working :)

@NotSqrt
Copy link

NotSqrt commented Sep 2, 2015

An example with a picture:

picture = slide.shapes.add_picture(
    image, Cm(left), Cm(top), height=Cm(height)
)
# move picture to background
slide.shapes._spTree.remove(picture._element)
slide.shapes._spTree.insert(2, picture._element)  # use the number that does the appropriate job

@scanny
Copy link
Owner Author

scanny commented Sep 2, 2015

Awesome, thanks @NotSqrt :)

@smcpherson
Copy link

+1 for this feature request. I tried the example above but it seems to create a slide that crashes powerpoint when opened.

@BarryArch
Copy link

BarryArch commented Jun 6, 2017

when I try to do this :

shape = shapes.add_shape(MSO_SHAPE.RECTANGLE,left,top,width,height)
slide.shapes._spTree.remove(shape._element)

an error says:

shape object has no attribute_Element'

did I make a mistake here?

@scanny
Copy link
Owner Author

scanny commented Jun 6, 2017

Looks like a typo. All shapes have the attribute ._element, not ._Element.

@BarryArch
Copy link

It is not a typo actually, I typed shape._element or shape._Element , Error always says:

shape object has no attribute '_Element'

Not a typo

@scanny
Copy link
Owner Author

scanny commented Jun 7, 2017

What is the type of the object you get back?

shape = shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
print(shape.__class__)  # or perhaps print(shape.__class__.__name__)

And what available attributes to you find when you introspect into shape?

print(dir(shape))

@chrismcmc
Copy link

Is there a workaround other than using _spTree.remove and _spTree.insert? It creates corrupted pptx files which generate an alert when opening in MS Powerpoint. Thanks

@scanny
Copy link
Owner Author

scanny commented Aug 5, 2017

I don't believe you have to actually remove and insert to change the order. Perhaps counterintuitive to the naming, I believe the .addprevious() and .addnext() lxml methods actually move the XML element in question.

So you could do something like this to move a shape from ninth position to fourth:

# shape will be positioned relative to this one, hence the name "cursor"
cursor_sp = shapes[3]._element

cursor_sp.addprevious(shapes[8]._element)

@chrismcmc
Copy link

chrismcmc commented Aug 5, 2017

thanks @scanny! I used the following to move a picture I added using add_picture to the background:

cursor_sp = shapes[0]._element
cursor_sp.addprevious(pic._element)

MS Powerpoint opens the file without complaining

@scanny
Copy link
Owner Author

scanny commented Aug 5, 2017

@chrismcmc Glad to hear you got it working :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants