Create Custom Property Groups in FreeCAD Scripts

Organizing custom parameters into logical property groups makes parametric objects in FreeCAD much easier to navigate and maintain. In FreeCAD's Python API, property groups are not separate containers that need explicit initialization; instead, they are created automatically when you specify a group name while attaching a property to an object. This guide covers how to define, group, and manage custom properties on document objects using FreeCAD Python scripts.

The addProperty Method

To create a custom property and assign it to a group, use the addProperty method available on any FreeCAD document object. The syntax is:

obj.addProperty(type, name, group="", doc="", attr=0, read_only=False, hidden=False)
  • type: The C++ type of property to instantiate (e.g., "App::PropertyLength", "App::PropertyString", "App::PropertyFloat").
  • name: The internal identifier for the property.
  • group: The string representing the group header in the FreeCAD Property View. If this group does not exist, FreeCAD creates it.
  • doc: The tooltip description displayed when hovering over the property in the GUI.

Adding Grouped Properties to an Object

The following script creates a generic Python feature, attaches properties under distinct groups (Dimensions and Manufacturing), and assigns default values to them.

import FreeCAD as App

# Ensure an active document exists
doc = App.activeDocument()
if not doc:
    doc = App.newDocument("PropertyGroupDemo")

# Create a generic FeaturePython object
obj = doc.addObject("App::FeaturePython", "ParametricItem")

# Add properties assigned to the "Dimensions" group
obj.addProperty("App::PropertyLength", "Length", "Dimensions", "Length of the object")
obj.addProperty("App::PropertyLength", "Width", "Dimensions", "Width of the object")
obj.addProperty("App::PropertyLength", "Height", "Dimensions", "Height of the object")

# Add properties assigned to the "Manufacturing" group
obj.addProperty("App::PropertyString", "Material", "Manufacturing", "Material type")
obj.addProperty("App::PropertyInteger", "BatchNumber", "Manufacturing", "Production batch ID")
obj.addProperty("App::PropertyBool", "QualityPassed", "Manufacturing", "Inspection status")

# Assign default values
obj.Length = 100.0
obj.Width = 50.0
obj.Height = 25.0
obj.Material = "Aluminum 6061"
obj.BatchNumber = 4021
obj.QualityPassed = True

# Recompute document to update the interface
doc.recompute()

Implementing Groups in Custom FeaturePython Classes

When building custom parametric objects with proxy classes, define property groups within the object initialization method:

class CustomBox:
    def __init__(self, obj):
        obj.Proxy = self
        
        # Geometry Parameters
        obj.addProperty("App::PropertyLength", "TotalLength", "Geometry", "Total length").TotalLength = 10.0
        obj.addProperty("App::PropertyLength", "TotalWidth", "Geometry", "Total width").TotalWidth = 10.0
        
        # Display/Metadata Parameters
        obj.addProperty("App::PropertyString", "PartID", "Identification", "Unique Part Number").PartID = "PART-001"

    def execute(self, obj):
        # Implementation logic for rebuilding geometry
        pass

# Instantiation
doc = App.ActiveDocument
box_obj = doc.addObject("Part::FeaturePython", "BoxObject")
CustomBox(box_obj)
doc.recompute()

Adding Properties to the View Tab

By default, calling addProperty on obj places properties under the Data tab of the Tree/Property View. If you need custom property groups to appear under the View tab (for controlling visualization settings), attach them to obj.ViewObject:

if App.GuiUp:
    view_obj = obj.ViewObject
    view_obj.addProperty("App::PropertyColor", "HighlightColor", "Custom Visuals", "Color for selection")
    view_obj.HighlightColor = (1.0, 0.0, 0.0)

Managing Existing Properties

  • Listing Properties: You can query all properties on an object using obj.PropertiesList.
  • Finding the Group: To find which group a property belongs to, use obj.getGroupOfProperty("PropertyName").
  • Removing Properties: Dynamically added properties can be removed using obj.removeProperty("PropertyName"). When all properties assigned to a custom group are removed, FreeCAD automatically removes the group header from the interface.