Welcome, guest | Sign In | My Account | Store | Cart
NOTE: Recipes have moved! Please visit GitHub.com/activestate/code for the current versions.

Autodesk's AutoCAD drafting software has for a number of versions included an increasingly complete COM interface. Using the Python win32com modules we have been able to automate some aspects the software; unfortunately because of the organization of the interface certain methods and properties were inaccessible from Python. In recent versions of the win32 modules a new function has been added though: win32com.client.CastTo(). By casting our objects as the correct type we now have access to much of the object model that used to be unreachable.

In this example we search the ModelSpace collection for text objects. Once found we then cast them and alter one of the text specific properties. To test this code open AutoCAD and in a blank file add at least one dtext object with 'Spam' as its value.

Python, 15 lines
import win32com.client
acad = win32com.client.Dispatch("AutoCAD.Application")

doc = acad.ActiveDocument   # Document object
ms = doc.ModelSpace         # Modelspace "collection"
count = ms.Count            # Number of items in modelspace

for i in range(count):
    item = ms.Item(i)
    if 'text' in item.ObjectName.lower(): # Text objects are AcDbText
        # once we know what it is we can cast it
        text = win32com.client.CastTo(item, "IAcadText") 
        if text.TextString == "Spam":
            text.TextString = "Maps"

Using this technique you can automate Windows programs using interfaces that in the past would have raised attribute errors. Python programmers know it is superior to VBA in virtually every way, but the lack of casting limited Python's usefulness for COM automation. Now though we can make Python treat COM objects as what they really are, saving Python programmers the pain of using VB to get work done under Windows.

1 comment

xiaoping wu 10 years ago  # | flag

modify entity position is wrong. from array import array import win32com.client acad = win32com.client.Dispatch("AutoCAD.Application.16") doc=acad.ActiveDocument ms = doc.ModelSpace

p = (10.0,10.0,0.0)

count = ms.Count total_text = 0 point=(0.0,0.0,0.0) for i in range(count): item = ms.Item(i) if 'text' in item.ObjectName.lower(): total_text = total_text + 1 text = win32com.client.CastTo(item, "IAcadText") if text.TextString == "1": text.TextString = "Maps" point = text.InsertionPoint x=point[0] y=point[1] z=point[2] x=x+10.0 text.InsertionPoint =(x,y,z)#is wrong,how to do text.Update() doc.Utility.Prompt("There are " + str(total_text) + " text objects in ModelSpace\n")