How to get the correct left position of a shape within a group when using python-pptx? - python-3.x

I am parsing a simple PowerPoint with three shapes. One shape is visibly to the left of the two other. But not when comparing it using python-pptx. The right side of that left shape (shape.left+shape.width) has a higher value than one of the other shapes left side (shape.left). The python-pptx result seem to indicate the right-hand shape starts within the left-hand shapes border. This seem to be caused by the group shape the right-hand shape is within.
What is the proper code to compare correctly that the right-hand shapes left side in fact is to the right of the left-hand shape?
I have tried removing the group, and then comparisons show expected values. I have tried creating new group shapes with shapes within, and again, they show expected values. However, the linked PowerPoint file at www.mibnet.se/LeftBoxIssue.pptx is an example where the group shape affects the normal result. When running the code, I do not know how the shapes were created. I need a generic way to test this special case correctly.
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
strStartPowerPoint=r".\LeftBoxIssue.pptx"
prs=Presentation(strStartPowerPoint)
slide=prs.slides[0]
for shpShape in slide.shapes:
if shpShape.shape_type == MSO_SHAPE_TYPE.GROUP:
print(shpShape.shapes[0].text+
" has Left="+str(shpShape.shapes[0].left)+
" and right="+
str(shpShape.shapes[0].left+shpShape.shapes[0].width))
else:
print(shpShape.text+" has Left="+str(shpShape.left)+
" and right="+str(shpShape.left+shpShape.width))
I expect the right hand shape to have its "left" value greater than the left-hand shapes "right" value. But instead, it prints a smaller value:
Left has Left=160326 and right=6254527
Right has Left=3291751 and right=3846370

A good place to start in understanding this is inspecting the group-shape XML:
print(group_shape._element.xml)
There you will find a child element that looks like this:
<p:grpSpPr>
<a:xfrm>
<a:off x="3347864" y="2204864"/>
<a:ext cx="3506688" cy="2930624"/>
<a:chOff x="3347864" y="2204864"/>
<a:chExt cx="3506688" cy="2930624"/>
</a:xfrm>
</p:grpSpPr>
The <a:chOff> element represents the "child-offset" of shapes within the group. In this case, which is typical of shapes grouped in python-pptx, note that the a:chOff values are exactly the same as the a:off values, which represent the top-left corner of the group-shape.
Using these two sets of values, you can calculate some interesting positions.
Absolute position of child shapes. This is child a:off plus group a:off minus group a:chOff.
Relative position of child shapes (to the group-shape origin). This is child a:off minus group a:chOff.
You can get these extra child-offset values from the group with:
chOff = group_shape._element.xpath("./p:grpSpPr/a:xfrm/a:chOff")[0]
chOff_x = int(chOff["x"])
chOff_y = int(chOff["y"])
These values are in English Metric Units (EMU) which are described here along with how you might conveniently manipulate them:
https://python-pptx.readthedocs.io/en/latest/user/autoshapes.html#understanding-english-metric-units
python-pptx always uses a child offset equal to the group shape position (a:off) because that is convenient. Other packages may use other group-shape offsets that are more convenient to their purposes. For example, if you were to move a group, you could accomplish that by changing a:off in the group only, without having to visit and update each of the child shape positions.

Related

Selecting multiple points of a series in a line chart

I know I can select a point of a series as follows:
ActiveChart.FullSeriesCollection(SeriesCollectionIndex).Points(100).Select
With this method I can operate on points one at a time. So, If I want to operate on all points in the range [100, 200] I can use a loop, but it is VERY slow. Is there a way to select the range of points, so I can operate on them all at once?
I tried
ActiveChart.FullSeriesCollection(SeriesCollectionIndex).Points("100:200").Select
but I get a
type mismatch error (the specification of the "point" expects a
number).
I cannot find any documentation on this or any sample code.

Is there a quick way to find the correct coordinate parameters for get_overlapping?

it's pretty tedious working out the dimensions of an image then halving it and adding it on every time I want to check whether something is overlapping.
You likely want to use bbox.
This 'returns the bounding box for all matching items', i.e. the rectangle outline of the picture you want to get the coordinates of.
coords = canvas.bbox(item)
or
coords = canvas.bbox("itemtag")
In the case of multiple items with the same tag, it will use the first item given that tag.

PyQt5 - Make labels in a grid expand dynamically without covering other items

I have a QGridLayout instance in a window, to which I dynamically add a series of widgets, depending on which values are checked on another QListView instance.
For each checked item in the list, I add a slider and two labels (for value and name), on a row of the layout, in positions 0, 1, 2.
for index in range(self.model.rowCount()):
if self.model.item(index).checkState():
slid = QSlider(Qt.Horizontal)
sl_val_lbl = QLabel("--")
sl_val_lbl.setMaximumWidth(150) #(a)
#sl_val_lbl.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) #(b)
sl_name_lbl = QLabel(self.model.item(index).text())
#sl_name_lbl.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
self.sliders.addWidget(slid,index,0)
slid.setMaximumWidth(200)
self.sliders.addWidget(sl_val_lbl,index,1)
self.sliders.addWidget(sl_name_lbl,index,2)
self.sliders_dict[sl_name_lbl.text()] = (slid,sl_val_lbl,sl_name_lbl)
Now, the issue I have is that some of the values the label takes, are actually pretty long strings.
My first solution was (a), i.e. set a certain size for the label. Of course, this may or may not work depending on the actual size of the text to be rendered, and when said text is only few chars long as in the case with floats, this is not a very clean solution.
I then went on trying (b), i.e. setting the expanding policy of the Qlabel to Expanding. This works fine for the label itself, however it goes to overlap with the next Qlabel in the Layout (column 2), covering its value.
In other words, I was expecting the underlying layout structure to stretch with the contained Widgets, which is not happening.
How to obtain the desired effect of having the size of the column in the layout to follow/adapt to that of the contained widgets?

How to combine to shapes into one? Sketch

I have just installed sketch and I am trying to create a circle with a tick sign inside.
The issue is that whenever I use the Union option to merge the circle and tick sign the tick sign is hidden. Here are the steps.
Insert -> Shape -> Oval
Insert -> Vector
I draw the tick sign
Select all layers specified above and click on union.
Tick sign is no longer shown inside the circle.
You can select both and create a symbol. Then export the symbol. You don't need union for this since you don't have any of the two shapes protruding outside the other.
The union creates a newer shape with the outer boundaries of the elements. In your case, the check mark is inside the circle and the result is just the circle. The right operation would be:
1 convert the check mark into an outline (Shift + Cmd + O)
2 select the circle and the checkmark
3 use the option subtract so the new shape would be the circle minus the checkmark.
You can just Group the two layers in step 4, rather than Union. Wouldn't that accomplish what you're looking to do?

How to get Dimension Breadcrumb in Excel pulling from Microsoft SSAS

TL;DR: How can I enable the option to precede the hierarchy name by the dimension name?
I am trying to implement a change that appears in one of the cubes I am working on based on the same dimension in another cube. When a user creates a pivot table on top of the correct cube in Excel, the dimension list appears as:
Where the hierarchy is preceded by the dimension name. When I implement the same dimension on my cube, it appears as:
This is different in that the example cube has the Dimension name preceding the Hierarchy while my working cube does not.
I looked through the properties of the dimensions and they appear to be the same. Specifically, the HierarchyUniqueNameStyle property of the dimension is set to IncludeDimensionName. My intuition says that this difference might be on the cube itself, since multiple dimensions of the example cube have the same feature.
Is there is another place where cube display attributes reside? Or, is this something where the developer of the example cube just changed the name?
In order for the bread crumb to show up, it requires two things. The first thing that is required is that the IncludeDimensionName property on the dimension must be set to true.
Secondly, the dimension must be a role-playing dimension, or, in other words, used in the cube multiple times.
When both of those conditions are satisfied, the bread crumb as shown in the first picture will appear.

Resources