5. Apps

RoboDK Apps (or Add-ins) allow you to extend RoboDK features and customize the look of RoboDK. Any application or script can be easily converted to a RoboDK Add-in to automate certain tasks, perform specific actions or facilitate a user’s workflow.

You can integrate scripts as part of the RoboDK user interface and easily customize RoboDK for customized offline programming and simulation purposes. Adding scripts to an App will add buttons in the menu and the toolbar automatically.

A settings file allows you to easily customize the appearance of a specific set of buttons/actions. A readme.md file allows you to publishing the app to the RoboDK Add-in marketplace: https://robodk.com/addins.

Once you complete developing your App you can easily distribute your App as a self-contained package file (rdkp file).

Apps are handled by RoboDK with the AppLoader Add-in, and roboapps provides the necessary Python tools to build your App.

You can find more information about the AppLoader in our GitHub:
You can find sample Apps in our GitHub:

5.1. App Template

This App example provides the necessary examples to build a RoboDK App. It can be used as a template to build your own RoboDK Apps. Note that

Please visit our GitHub to get the complete App:

5.1.1. Actions

The most common action type is the momentary action (on click). It is useful to run on-demand scripts.

RoboDK Apps - Momentary Action
# --------------------------------------------
# --------------- DESCRIPTION ----------------
#
# Momentary action example.
#
# More information about the RoboDK API for Python here:
#     https://robodk.com/doc/en/RoboDK-API.html
#     https://robodk.com/doc/en/PythonAPI/index.html
#
# More information on RoboDK Apps here:
#     https://github.com/RoboDK/Plug-In-Interface/tree/master/PluginAppLoader
#
# --------------------------------------------

from robodk import robolink, roboapps
from _AppUtilities import ShowMessage
import os

ACTION_NAME = os.path.basename(__file__)


def ActionMomentary():
    """Action to perform when the action is clicked in RoboDK."""

    RDK = robolink.Robolink()
    ShowMessage(RDK, ACTION_NAME, "Clicked!", True)


def runmain():
    """
    Entrypoint of this action when it is executed on its own or interacted with in RoboDK.
    Important: Use the function name 'runmain()' if you want to compile this action.

    Example for a 'Checkable Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Momentary Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                roboapps.Exit()  # or sys.exit()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Checkable Option':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.KeepChecked()  # Important, prevents RoboDK from unchecking the action after it has completed
                ActionChecked()

    """

    if roboapps.Unchecked():
        roboapps.Exit()
    else:
        ActionMomentary()


if __name__ == '__main__':
    runmain()

The checkable action (toggle) is useful for running continuous scripts.

RoboDK Apps - Checkable Action
# --------------------------------------------
# --------------- DESCRIPTION ----------------
#
# Checkable action example.
#
# The main icon for this action is automatically loaded as it shares the same name (ActionCheckable[.py, .svg]).
# The checked icon loaded as it is suffixed with 'Checked'.
#
# More information about the RoboDK API for Python here:
#     https://robodk.com/doc/en/RoboDK-API.html
#     https://robodk.com/doc/en/PythonAPI/index.html
#
# More information on RoboDK Apps here:
#     https://github.com/RoboDK/Plug-In-Interface/tree/master/PluginAppLoader
#
# --------------------------------------------

from robodk import robolink, robomath, roboapps
from _AppUtilities import ShowMessage
import os

ACTION_NAME = os.path.basename(__file__)


def ActionChecked():
    """Action to perform when the action is checked in RoboDK."""

    RDK = robolink.Robolink()
    APP = roboapps.RunApplication()

    ShowMessage(RDK, ACTION_NAME, "Checked! Waiting to be unchecked..", True)

    i = 0
    while APP.Run():
        ShowMessage(RDK, ACTION_NAME, "Checked Status.. " + str(i), False)
        robomath.pause(0.25)
        i += 1

    # This will not be called if SkipKill() is not present
    robomath.pause(3)
    ShowMessage(RDK, ACTION_NAME, "Unchecked! This is a post-run message (SkipKill). Closing..", True)


def ActionUnchecked():
    """Action to perform when the action is unchecked in RoboDK."""

    # It is not recommended to use APP.Run() in the Unchecked state!
    RDK = robolink.Robolink()
    ShowMessage(RDK, ACTION_NAME, "Unchecked!", True)
    return


def runmain():
    """
    Entrypoint of this action when it is executed on its own or interacted with in RoboDK.
    Important: Use the function name 'runmain()' if you want to compile this action.

    Example for a 'Checkable Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Momentary Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                roboapps.Exit()  # or sys.exit()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Checkable Option':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.KeepChecked()  # Important, prevents RoboDK from unchecking the action after it has completed
                ActionChecked()

    """

    if roboapps.Unchecked():
        ActionUnchecked()
    else:
        roboapps.SkipKill()  # Comment this line to have RoboDK kill the process after 2 seconds (if it still runs)
        ActionChecked()


if __name__ == '__main__':
    runmain()

The contextual action (right-click menu) has the same capabilities has the momentary and checkable actions, but is bound to user selection. It is useful to perform actions on specific items.

RoboDK Apps - Contextual Action
# --------------------------------------------
# --------------- DESCRIPTION ----------------
#
# Context action example (right-click a tree item of a specific type).
#
# More information about the RoboDK API for Python here:
#     https://robodk.com/doc/en/RoboDK-API.html
#     https://robodk.com/doc/en/PythonAPI/index.html
#
# More information on RoboDK Apps here:
#     https://github.com/RoboDK/Plug-In-Interface/tree/master/PluginAppLoader
#
# --------------------------------------------

from robodk import robolink, roboapps
from _AppUtilities import ShowMessage
import os

ACTION_NAME = os.path.basename(__file__)


def OnContextAction():
    """Action to perform when the action is clicked in RoboDK."""

    RDK = robolink.Robolink()

    selected_items = RDK.Selection()
    if not selected_items:
        ShowMessage(RDK, ACTION_NAME, "Nothing selected!", True)
        return

    names = [x.Name() for x in selected_items]
    ShowMessage(RDK, ACTION_NAME, 'User selected ' + ', '.join(names) + '.', True)


def runmain():
    """
    Entrypoint of this action when it is executed on its own or interacted with in RoboDK.
    Important: Use the function name 'runmain()' if you want to compile this action.

    Example for a 'Checkable Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Momentary Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                roboapps.Exit()  # or sys.exit()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Checkable Option':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.KeepChecked()  # Important, prevents RoboDK from unchecking the action after it has completed
                ActionChecked()

    """

    if roboapps.Unchecked():
        roboapps.Exit()
    else:
        OnContextAction()


if __name__ == '__main__':
    runmain()

5.1.2. Options

The checkable option (toggle) is useful to provide status to the user. You can also group options, so that they are mutually exclusive.

RoboDK Apps - Checkable Option
# --------------------------------------------
# --------------- DESCRIPTION ----------------
#
# Checkable option example.
#
# More information about the RoboDK API for Python here:
#     https://robodk.com/doc/en/RoboDK-API.html
#     https://robodk.com/doc/en/PythonAPI/index.html
#
# More information on RoboDK Apps here:
#     https://github.com/RoboDK/Plug-In-Interface/tree/master/PluginAppLoader
#
# --------------------------------------------

from robodk import robolink, roboapps
from _AppUtilities import ShowMessage
from AppSettings import Settings
import os

ACTION_NAME = os.path.basename(__file__)


def ActionChecked():
    """Action to perform when the action is checked in RoboDK."""

    RDK = robolink.Robolink()
    S = Settings()
    S.Load(RDK)

    RDK.setParam(S.APP_OPTION_KEY, 1.0)
    ShowMessage(RDK, ACTION_NAME, str(RDK.getParam(S.APP_OPTION_KEY)), False)


def ActionUnchecked():
    """Action to perform when the action is unchecked in RoboDK."""

    RDK = robolink.Robolink()
    S = Settings()
    S.Load(RDK)

    RDK.setParam(S.APP_OPTION_KEY, 0.0)
    ShowMessage(RDK, ACTION_NAME, str(RDK.getParam(S.APP_OPTION_KEY)), False)


def runmain():
    """
    Entrypoint of this action when it is executed on its own or interacted with in RoboDK.
    Important: Use the function name 'runmain()' if you want to compile this action.

    Example for a 'Checkable Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Momentary Action':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                roboapps.Exit()  # or sys.exit()
            else:
                roboapps.SkipKill()  # Optional, prevents RoboDK from force-killing the action after 2 seconds
                ActionChecked()

    Example for a 'Checkable Option':

    .. code-block:: python

        def runmain():
            if roboapps.Unchecked():
                ActionUnchecked()
            else:
                roboapps.KeepChecked()  # Important, prevents RoboDK from unchecking the action after it has completed
                ActionChecked()

    """

    if roboapps.Unchecked():
        ActionUnchecked()
    else:
        roboapps.KeepChecked()
        ActionChecked()


if __name__ == '__main__':
    runmain()

5.1.3. Configuration

A configuration is needed to determine the action type, names, description, etc.

RoboDK Apps - App Config
[General]
MenuName=App Example
MenuParent=
MenuPriority=50
MenuVisible=true
ToolbarArea=2
ToolbarSizeRatio=1.5
RunCommands=
Version=1.0.0

[ActionCheckable]
DisplayName=Checkable Action
Description=Checkable action example
Visible=true
Shortcut=
Checkable=true
CheckableGroup=-1
AddToToolbar=true
Priority=10
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[ActionMomentary]
DisplayName=Momentary Action
Description=Momentary action example
Visible=true
Shortcut=
Checkable=false
CheckableGroup=-1
AddToToolbar=true
Priority=20
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[ActionOnContext]
DisplayName=Contextual Action
Description=Contextual action example
Visible=true
Shortcut=
Checkable=false
CheckableGroup=-1
AddToToolbar=false
Priority=30
TypeOnContextMenu=-1
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[ActionOnDoubleClick]
DisplayName=Double-Click Action
Description=Double click action example
Visible=true
Shortcut=
Checkable=false
CheckableGroup=-1
AddToToolbar=false
Priority=31
TypeOnContextMenu=
TypeOnDoubleClick=-1
DeveloperOnly=false
AddToMenu=true

[OptionCheckable]
DisplayName=Checkable Option
Description=Checkable option example
Visible=true
Shortcut=
Checkable=true
CheckableGroup=-1
AddToToolbar=false
Priority=40
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[OptionCheckableGroupA]
DisplayName=Checkable Option (Group) A
Description=Checkable option (group) A example
Visible=true
Shortcut=
Checkable=true
CheckableGroup=1
AddToToolbar=false
Priority=50
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[OptionCheckableGroupB]
DisplayName=Checkable Option (Group) B
Description=Checkable pption (group) B example
Visible=true
Shortcut=
Checkable=true
CheckableGroup=1
AddToToolbar=false
Priority=51
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true

[AppSettings]
DisplayName=Settings
Description=Edit the example settings
Visible=true
Shortcut=
Checkable=false
CheckableGroup=1
AddToToolbar=false
Priority=100
TypeOnContextMenu=
TypeOnDoubleClick=
DeveloperOnly=false
AddToMenu=true