Can't update TextElement text

972
9
Jump to solution
07-11-2018 12:45 PM
JoshuaBrengel
New Contributor III

I've read just about every post on the internet about updating and/or adding TextElements using arcpy.  I am not able to get the text in my TextElement object to update.

The portion of my script is:

pop_cent = ('Harrisburg', 'Middletown', 'Hershey', 'Halifax', 'Elizabethville')


    if os.path.exists(newpath) == False:
        mxd = arcpy.mapping.MapDocument(inpath) #Create map document object using basemap
        mxd.saveACopy(newpath) # Copy the basemap from Adams for adding appropriate data

        copy_mxd = arcpy.mapping.MapDocument(newpath) # Create map document object using copied basemap
        df = arcpy.mapping.ListDataFrames(copy_mxd, "Layers")[0] #lists the dataframe object to use in AddLayer
        x = df.elementPositionX
        print x
        y = df.elementPositionY
        print y
       
        orig_text = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT")
        for d, pop in enumerate(pop_cent):
            orig_text[d].text = pop_cent[d]
            print(orig_text[d].text)
            orig_text[d].elementPositionX = x
            orig_text[d].elementPositionY = y
            arcpy.RefreshActiveView()

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The script successfully moves the TextElement to where I want in the "copy_mxd" and the print statement in line 18 provides the correct string from pop_cent.  But, the actual TextElement's text does not update the text.  Why?

Based on what I've read online, is it because not all the TextElements are embedded in a focused dataframe?  Or perhaps I'm trying to go between two different map documents (mxd and copy_mxd) with TextElements?  Or do I need to somehow access the LayoutView using the mapping module?

Thank you,

Josh

PS Using ArcMap 10.4 on Windows 7, Python 32-bit.

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Alum

I have found that it helps if the text elements have a name.

import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):
    if elm.name == "UpdateText":
        elm.text = "Halifax"

arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
del mxd
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Does the base map you are starting with contain a text element, or are you wanting to add a new text element?  Or to add/update 5 overlapping text elements?

View solution in original post

0 Kudos
9 Replies
DarrenWiens2
MVP Honored Contributor

Can you try adding mxd.save() to the end?

0 Kudos
JoshuaBrengel
New Contributor III

Hi Darren,

Sorry for late reply.  I put your suggestion near the end of my script, outside of the for loop on line 16.  I'm guessing you're suggesting I put it inside the for loop?  Also, I should note that I apply the .save() method to the "copy_mxd" map document.  Thank you!

0 Kudos
RandyBurton
MVP Alum

I have found that it helps if the text elements have a name.

import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")

for elm in arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT"):
    if elm.name == "UpdateText":
        elm.text = "Halifax"

arcpy.RefreshTOC()
arcpy.RefreshActiveView()
mxd.save()
del mxd
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Does the base map you are starting with contain a text element, or are you wanting to add a new text element?  Or to add/update 5 overlapping text elements?

0 Kudos
JoshuaBrengel
New Contributor III

Hi Randy,

Apologies for the late reply.  Appreciate the suggestions.  My original map (ie "mxd" from my original code) contains existing text elements representing towns, as well as text elements for watershed names and the ESRI service credits (which apparently are text elements, too). 

Because I move the text elements to a different geographic location, all I really want to do is create 5 new text elements in the new map (ie "copy_mxd" from my original code) that are the five towns in the "pop_cent" variable in the code.  I was hoping I could just take one text element from the original map and iteratively copy and replace it with the 5 towns from the pop_cent tuple, while moving it to a different geographic location.  I would end up with 5 next text elements in the new map with town names.

I haven't heard the idea of naming text elements before so I will give that a try.

Where do you suggest I put the "RefreshTOC", "RefreshActiveView", and "save" methods, inside or outside the for loop on line 16?  Thank you!

0 Kudos
JoshuaBrengel
New Contributor III

Never mind about where to place those three methods.  I see now that based on your code, it's outside the for loop.  Thanks.

0 Kudos
RandyBurton
MVP Alum

I was a bit confused by your loop.  You were looping through your pop_cent list instead of your text elements.  If you didn't have the same number of text elements as in your list, you would get an indexing error.  I would suggest that your template map have a number of text elements available and named - the content can be an empty string or spaces.  Then you can check if the name is a certain value, then set the text value and position as necessary.

JoshuaBrengel
New Contributor III

Yeah, I realize that was a limitation.  See my recent reply.  It may not be a best practice, but I based on the maps I'm creating, I won't need more than 7 text elements in the new map.  So, I just created 7 text elements in the original map.

0 Kudos
JoshuaBrengel
New Contributor III

Randy,

Giving the text element a name worked like a charm in order to update the corresponding text, thanks!  I still don't exactly know how I would copy a single text element from the original map, but I just created a bunch of text elements in the original map to pull from and rename in my new map.

- Josh

0 Kudos
RandyBurton
MVP Alum

Glad it worked.

0 Kudos