Is there a quick way to find the correct coordinate parameters for get_overlapping? - python-3.x

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.

Related

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

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.

react-virtualized List: How to remove empty space when the list is too short?

I am using react-virtualized List to render a list of data. When the list is too short (is height is smaller than the "height" prop of List component) there are a lot of empty spaces at the bottom (because the height is fixed). Is there any way to fix this problem?
The fix is to detect when this is the case, and just pass a shorter height value to List.
This is what react-virtualized-selected does for short drop-down lists, for example. You can see the code for that here, although it may be more complicated than what you need because of the fact that it supports variable-height rows.
If your rows are fixed height, then the calculation is much simpler:
const height = Math.min(maxHeight, rowCount * rowHeight);

How to Subtract a Vector Path from a Rectangle in Sketch

How does one subtract a vector path in Sketch. Shapes are straightforward and text is also doable. The white lines in the attached images need to be cuts through the rectangle. Suggestions?
You need to convert the vector-path to outlines first.
Select the desired element with outlines
Choose inside the menu: Layer > Convert to Outlines (⇧⌘O)
Select the elements you want to combine
Choose (Subtract, Intersect or Difference)
Update: added an inline GIF for better visual reference

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?

svg concatenate text of different styles

I am using d3 to create an axis label inside an svg element. Part of the label is constant (string literal) and part of it varies as the user clicks around. To emphasize that it changes, I want it to be bold, while the rest of the text is normal weight. Aligning these two text elements, to each other and the rest of the drawing, has turned out to be quite difficult.
Also, it seems trailing spaces in text elements are ignored, making it harder to do the concatenation. And if there's a way to change styles within a text element, that would work too.
Here is a very hacky way of doing it, in that it won't work with three pieces of text (because text-anchor), and the result is hard to center (do I really need to go use getBBox()?).
function renderLabel(dynamicText){
svg.select(".label").remove();
var label = svg.append("g")
.attr("class", "label")
label.append("text")
.attr("text-anchor", "end")
.text("The Axis is Based On ");
label.append("text")
.attr("text-anchor", "start")
.style("font-weight", "bold")
.attr("transform", "translate(6,0)") //space
.text(dynamicText);
}
In general, I would like to be able to append/concatenate any number of string variables, each with distinct styles, in a way that "looks good" as a sentence, and can be centered. Please tell me there's a better way to do it.
Instead of using separate text elements, use one text element with two tspan elements nested inside. If you do not set separate positioning attributes on the tspan, they will naturally line up as one row of text.
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/tspan

Resources