Create Custom Commands in FreeCAD Python Workbenches

Creating custom command classes in FreeCAD allows developers to extend the software's functionality by binding Python logic to graphical user interface elements like toolbar buttons and menu items. This guide covers how to structure a FreeCAD Python command class using standard methods such as GetResources, Activated, and IsActive, register it with the FreeCAD GUI, and add it to a custom workbench toolbar and menu.

Structure of a Custom Command Class

In FreeCAD, a GUI command is defined as a Python class. This class must implement specific methods that the FreeCAD interface expects:

  • GetResources(self): Returns a dictionary defining the tool's metadata, such as its display name, tooltip, accelerator key, and icon path.
  • Activated(self): Contains the primary logic executed when the user clicks the tool button or menu item.
  • IsActive(self) (Optional): Returns a boolean indicating whether the command should currently be enabled or grayed out (for example, requiring an active document or a specific selection).

Basic Command Implementation

Create a Python file (such as my_commands.py) within your workbench directory and define your command class:

import FreeCAD
import FreeCADGui

class CreateBoxCommand:
    """A custom command that creates a standard box."""

    def GetResources(self):
        return {
            'Pixmap': 'path/to/icon.svg',  # Optional: Path to icon or standard FreeCAD icon name
            'MenuText': 'Create Custom Box',
            'ToolTip': 'Creates a custom box in the active document',
            'Accel': 'Shift+B'             # Optional keyboard shortcut
        }

    def IsActive(self):
        # The command is only active if an open document exists
        return FreeCAD.ActiveDocument is not None

    def Activated(self):
        # Logic executed when triggered
        doc = FreeCAD.ActiveDocument
        box = doc.addObject("Part::Box", "CustomBox")
        box.Length = 10.0
        box.Width = 10.0
        box.Height = 10.0
        doc.recompute()
        FreeCAD.Console.PrintMessage("Custom Box created successfully.\n")

Registering the Command

Before the command can be used in menus or toolbars, it must be registered with the FreeCAD GUI using FreeCADGui.addCommand(). This connects an internal string identifier to an instance of your command class.

At the bottom of your command file (or in your workbench initialization), register the class:

FreeCADGui.addCommand('MyWorkbench_CreateBox', CreateBoxCommand())

Use a unique prefix (like your workbench name) to prevent naming collisions with core FreeCAD commands or other add-ons.

Adding the Command to a Workbench

To expose the command in your workbench interface, reference the registered command name inside your workbench's InitGui.py file.

import FreeCADGui

class MyWorkbench(FreeCADGui.Workbench):
    MenuText = "My Workbench"
    ToolTip = "A custom FreeCAD workbench"

    def Initialize(self):
        # Import command definitions so they register themselves
        import my_commands

        # Define toolbar and menu items using the registered command name
        command_list = ["MyWorkbench_CreateBox"]

        self.appendToolbar("Custom Tools", command_list)
        self.appendMenu("Custom Menu", command_list)

    def GetClassName(self):
        return "Gui::PythonWorkbench"

FreeCADGui.addWorkbench(MyWorkbench())

Once the workbench is loaded in FreeCAD, the command will appear in the specified toolbar and menu, dynamically updating its availability based on the IsActive method and running the Activated method upon invocation.