Setting background color of wordx - python

im trying to set a report default background color but it appears black instead of blue, can anyone help?
Why is that? do i need to use another format that is not hex? iv tryied with other format and still nothing.
docpath="/Users/ricardosimoes/Desktop/DESKTOP/Jira/my_word_file.docx"
mydoc = docx.Document()
section_h = mydoc.sections[0]
header = section_h.header
styles = mydoc.styles
style = styles.add_style('Tahoma',WD_STYLE_TYPE.PARAGRAPH)
style.font.name = 'Tahoma'
style.font.size = Pt(11)
shd = OxmlElement('w:background')
# Add attributes to the xml element
shd.set(qn('w:color'), '#0000FF')
shd.set(qn('w:themeColor'), 'text1')
shd.set(qn('w:themeTint'), 'F2')
# Add background element at the start of Document.xml using below
mydoc.element.insert(0, shd)
# Add displayBackgroundShape element to setting.xml
shd1 = OxmlElement('w:displayBackgroundShape')
mydoc.settings.element.insert(0, shd1)
paragraph_h = header.paragraphs[0]
runheader = paragraph_h.add_run()
runheader.add_picture("client_report/report_img/titulo.png", width=docx.shared.Inches(5), height=docx.shared.Inches(1))
mydoc.add_picture("client_report/report_img/bottom.png", width=docx.shared.Inches(5),
height=docx.shared.Inches(1))
mydoc.save(docpath)

The snippet seems to supply all three of the w:color, w:themeColor and w:themeTint attributes, and the latter two override the first one. The ECMA-376 standard says about the w:color attribute:
If the background specifies the use of a theme color via the themeColor attribute, this value is ignored. [Note: Applications are discouraged from specifying both the color and themeColor attributes on the same parent element. end note]
I haven't tested this, but removing themeColor and themeTint (and dropping the # from 0000FF) should cause the blue color to show up.

Related

select color attributes via python in blender

Is it possible to select color attributes in blender with python? Idea is to do the same like clicking on the vertex color in viewport. The goal is to make the colors visible in the viewport.
My current approach looks like this:
# accessing color attributes
test_1 = bpy.data.meshes['Cube'].color_attributes['test_1']
test_2 = bpy.data.meshes['Cube'].color_attributes['test_2']
# try to change selection
bpy.ops.geometry.color_attribute_render_set(name="test_2")
Unfortunately this is not working. Is there an easy approach to solve this? Thanks in advance.
Solved it by creating a material like this:
def create_mat():
mat = bpy.data.materials.new(name="test")
obj.data.materials.append(mat)
mat.use_nodes = True
mat.node_tree.nodes.new(type="ShaderNodeVertexColor")
mat.node_tree.nodes["Color Attribute"].layer_name = "test_1"
input = mat.node_tree.nodes["Principled BSDF"].inputs["Base Color"]
output = mat.node_tree.nodes["Color Attribute"].outputs["Color"]
mat.node_tree.links.new(input, output)
def change_mat():
mat = bpy.data.materials["test"]
mat.node_tree.nodes["Color Attribute"].layer_name = "test_2"
create_mat()
change_mat()

Python folium synchronizing 2 markerclusters

I have a situation, where I decided to distinguish my markers slightly by adding the MarkerCluster to the existing Marker.
The clustering works, although isn't synchronized. It means, that if I switch one layer off, just the first markercluster disappears, whereas the second criterion defined as CircleMarker still appears like shown below.
My code is:
df = pd.read_csv("or_geo.csv")
fo=FeatureGroup(name="OR",overlay = True)
openreach_cluster = MarkerCluster(name="OR").add_to(map)
openreach_status = MarkerCluster(control=False,
visible=True
).add_to(map)
for i,row in df.iterrows():
lat =df.at[i, 'lat']
lng = df.at[i, 'lng']
sp = df.at[i, 'sp']
stat = df.at[i,'status']
popup = df.at[i,'sp'] +'<br>' + str(df.at[i, 'street']) + '<br>' + str(df.at[i, 'post code']) + '<br>{}'.format(style)
or_marker = folium.Marker(location=[lat,lng], tooltip='<strong>Job details</strong>', popup=popup, icon = folium.Icon(
color='blue', icon='glyphicon-calendar'))
or_stat_marker = folium.CircleMarker(
location=[lat,lng],
radius=10,
color=or_color(stat),
fill_color=or_color(stat),
fill_opacity=0.5)
openreach_cluster.add_child(or_marker)
openreach_status.add_child(or_stat_marker)
Is there any way to combine these markerClusters together or sync them?
UPDATE:
The first approach from the answer below, unfortunately, doubles the jobs up and the user can't see them until clicks on any of them shown below:
This option would be fantastic if the behavior could be the same as in the image above.
UPDATE II:
The second approach is still not what I am looking for, because the clusters are doubled again and after clicking the circlemarker falls almost in the opposite direction as presented in the image above.
I need to have the behaviors exactly like those displayed on the top-left image. The circlemarker should be integrated with the point marker.
If I got you right, I think there are two possibilities:
Use the same cluster
Add your markers from or_stat_marker to the openreach_cluster and not to another cluster to de-/activate them at the same time with the same button
# was
openreach_cluster.add_child(or_marker)
openreach_status.add_child(or_stat_marker)
# try this
openreach_cluster.add_child(or_marker)
openreach_cluster.add_child(or_stat_marker)
Use marker subgroups
In this case you will have three checkmarks, one parent and two childs for each markercluster which gives full control to visibility
UPDATE: If you add the control=False option to the subgroup you will only see the parent group in LayerControl which then show/hide both groups. But the matter of markers "spreading for visibility" still is a problem I think
Another UPDATE: You are able to deactivate the clustering according to the map zoom level or even at all by using disableClusteringAtZoom option (use True or an int number for zoom level). See here for reference
# markergroups in layercontrol
mc = folium.plugins.MarkerCluster(name='OR',
overlay=True,
control=True,
show=True,
disableClusteringAtZoom=15) # choose zoom lvl to your needs
mc.add_to(map)
sub1 = folium.plugins.FeatureGroupSubGroup(mc, name='openreach_cluster', control=False, show=True) # False --> deactivated at start
sub1.add_to(map)
sub2 = folium.plugins.FeatureGroupSubGroup(mc, name='openreach_status', control=False)
sub2.add_to(map)
# the layercontrol itself
lc = folium.map.LayerControl(collapsed=False)
lc.add_to(map)
# ...
for i, row in df.iterrows():
# ...
or_marker = folium.Marker(...)
or_marker.add_to(sub1)
or_stat_marker = folium.CircleMarker(...)
or_stat_marker.add_to(sub2)
My Result:
By following the second approach described I get a map shown here. There is one checkmark "Segment Markers" which shows/hides the markers including the circles. They don't move around when clicked and are fully shown when zoomed in to a specific lvl by using disableClusteringAtZoom.
Sorry this didn't work for your problem, I really don't know why ..

Python-docx how to set font spacing?

How to set font spacing in python-docx or how to add element to w:rPr?
//<w:rPr> <w:spacing w:val="200"/> </w:rPr>
There is no API support for this setting in python-docx.
Adding a <w:spacing> element will work if that's what Word does, however the sequence in which child elements appear is, in general, significant in WordprocessingML (the XML schema .docx files adhere to). If you don't get the w:spacing element in the right order among the w:rPr child elements or you add one when one is already there, you'll trigger a repair error.
So you need something like this:
def run_set_spacing(run, value: int):
"""Set the font spacing for `run` to `value` in twips.
A twip is a "twentieth of an imperial point", so 1/1440 in.
"""
def get_or_add_spacing(rPr):
# --- check if `w:spacing` child already exists ---
spacings = rPr.xpath("./w:spacing")
# --- return that if so ---
if spacings:
return spacings[0]
# --- otherwise create one ---
spacing = OxmlElement("w:spacing")
rPr.insert_element_before(
spacing,
*(
"w:w",
"w:kern",
"w:position",
"w:sz",
"w:szCs",
"w:highlight",
"w:u",
"w:effect",
"w:bdr",
"w:shd",
"w:fitText",
"w:vertAlign",
"w:rtl",
"w:cs",
"w:em",
"w:lang",
"w:eastAsianLayout",
"w:specVanish",
"w:oMath",
),
)
return spacing
rPr = run._r.get_or_add_rPr()
spacing = get_or_add_spacing(rPr)
spacing.set("val", str(value))
Then you would call this for each run that needs that setting like so:
run_set_spacing(run, 200)
I tried the answer by scanny, It did not work. But the output document XML <w:spacing val="200"> is close to the right format.
The right format is <w:spacing w:val="200">
Try this
from docx.oxml.ns import qn
spacing.set(qn('w:val'), str(value))

Catia select a feature from a specific instance in an assembly

Lets say I have an assembly like this:
MainProduct:
-Product1 (Instance of Part1)
-Product2 (Instance of Part2)
-Product3 (Instance of Part2)
-Product4 (Instance of Part3)
...
Now, I want to copy/paste a feature from Product3 into another one.
But I run into problems when selecting the feature programmatically, because there are 2 instances of the part of that feature.
I can't control which feature will be selected by CATIA.ActiveDocument.Selection.Add(myExtractReference)
Catia always selects the feature from Product2 instead of the feature from Product3. So the position of the pasted feature will be wrong!
Does anybody know this problem and has a solution to it?
Edit:
The feature reference which I want to copy already exists as a variable because it was newly created (an extract of selected geometry)
I could get help else where. Still want to share my solution. It's written in Python but in VBA its almost the same.
The clue is to access CATIA.Selection.Item(1).LeafProduct in order to know where the initial selection was made.
import win32com.client
import pycatia
CATIA = win32com.client.dynamic.DumbDispatch('CATIA.Application')
c_doc = CATIA.ActiveDocument
c_sel = c_doc.Selection
c_prod = c_doc.Product
# New part where the feature should be pasted
new_prod = c_prod.Products.AddNewComponent("Part", "")
new_part_doc = new_prod.ReferenceProduct.Parent
# from user selection
sel_obj = c_sel.Item(1).Value
sel_prod_by_user = c_sel.Item(1).LeafProduct # reference to the actual product where the selection was made
doc_from_sel = sel_prod_by_user.ReferenceProduct.Parent # part doc from selection
hb = doc_from_sel.Part.HybridBodies.Add() # new hybrid body for the extract. will be deleted later on
extract = doc_from_sel.Part.HybridShapeFactory.AddNewExtract(sel_obj)
hb.AppendHybridShape(extract)
doc_from_sel.Part.Update()
# Add the extract to the selection and copy it
c_sel.Clear()
c_sel.Add(extract)
sel_prod_by_catia = c_sel.Item(1).LeafProduct # reference to the product where Catia makes the selection
c_sel_copy() # will call Selection.Copy from VBA. Buggy in Python.
# Paste the extract into the new part in a new hybrid body
c_sel.Clear()
new_hb = new_part_doc.Part.HybridBodies.Item(1)
c_sel.Add(new_hb)
c_sel.PasteSpecial("CATPrtResultWithOutLink")
new_part_doc.Part.Update()
new_extract = new_hb.HybridShapes.Item(new_hb.HybridShapes.Count)
# Redo changes in the part, where the selection was made
c_sel.Clear()
c_sel.Add(hb)
c_sel.Delete()
# Create axis systems from Position object of sel_prd_by_user and sel_prd_by_catia
prod_list = [sel_prod_by_user, sel_prod_by_catia]
axs_list = []
for prod in prod_list:
pc_pos = pycatia.in_interfaces.position.Position(prod.Position) # conversion to pycata's Position object, necessary
# in order to use Position.GetComponents
ax_comp = pc_pos.get_components()
axs = new_part_doc.Part.AxisSystems.Add()
axs.PutOrigin(ax_comp[9:12])
axs.PutXAxis(ax_comp[0:3])
axs.PutYAxis(ax_comp[3:6])
axs.PutZAxis(ax_comp[6:9])
axs_list.append(axs)
new_part_doc.Part.Update()
# Translate the extract from axis system derived from sel_prd_by_catia to sel_prd_by_user
extract_ref = new_part_doc.Part.CreateReferenceFromObject(new_extract)
tgt_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[0])
ref_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[1])
new_extract_translated = new_part_doc.Part.HybridShapeFactory.AddNewAxisToAxis(extract_ref, ref_ax_ref, tgt_ax_ref)
new_hb.AppendHybridShape(new_extract_translated)
new_part_doc.Part.Update()
I would suggest a differed approach. Instead of adding references you get from somewhere (by name probably) add the actual instance of part to selection while iterating trough all the products. Or use instance Names to get the correct part.
Here is a simple VBA example of iterating one lvl tree and select copy paste scenario.
If you want to copy features, you have to dive deeper on the Instance objects.
Public Sub CatMain()
Dim ActiveDoc As ProductDocument
Dim ActiveSel As Selection
If TypeOf CATIA.ActiveDocument Is ProductDocument Then 'of all the checks that people are using I think this one is most elegant and reliable
Set ActiveDoc = CATIA.ActiveDocument
Set ActiveSel = ActiveDoc.Selection
Else
Exit Sub
End If
Dim Instance As Product
For Each Instance In ActiveDoc.Product.Products 'object oriented for ideal for us in this scenario
If Instance.Products.Count = 0 Then 'beware that products without parts have also 0 items and are therefore mistaken for parts
Call ActiveSel.Add(Instance)
End If
Next
Call ActiveSel.Copy
Call ActiveSel.Clear
Dim NewDoc As ProductDocument
Set NewDoc = CATIA.Documents.Add("CATProduct")
Set ActiveSel = NewDoc.Selection
Call ActiveSel.Add(NewDoc.Product)
Call ActiveSel.Paste
Call ActiveSel.Clear
End Sub

"Send to back" a shape on PPT using python

I have script which adds a textbox with some text on an existing PPT. Now the textbox colour is made white to overwrite the existing text present in the slidemaster.
The issue is than a small part of textbox overlaps with another shape which is supposed to be on top. Is there an option in python-pptx to send the shape to back.
Below is the option which can be used using the powerpoint
Is the a way I can do this using python-pptx
here is my script
for pptfile in addressList:
prs = Presentation(pptfile)
slides = prs.slides
for i in range(2,len(slides)-1):
textContent = ""
slide = prs.slides[i]
# Text position
t_left = Inches(3.27)
t_top = Inches(7.05)
t_width = Inches(6.89)
t_height = Inches(0.27)
# Text
txBox = slide.shapes.add_textbox(t_left, t_top, t_width, t_height)
fill = txBox.fill
fill.solid()
fill.fore_color.rgb = RGBColor(255, 255, 255)
tf = txBox.text_frame.paragraphs[0]
tf.vertical_anchor = MSO_ANCHOR.TOP
tf.word_wrap = True
tf.margin_top = 0
tf.auto_size = MSO_AUTO_SIZE.SHAPE_TO_FIT_TEXT
run = tf.add_run()
run.text = "This is new text."
font = run.font
font.name = 'Univers LT Std 47 Cn Lt'
font.size = Pt(10)
font.bold = None
font.italic = None # cause value to be inherited from theme
font.color.rgb = RGBColor(157, 163, 163)
prs.save(pptfile)
print(pptfile," Done!")
This discussion in github might help you:
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 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 element, which would allow you to reorder shapes.
[...]
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)
See github question

Categories

Resources