Bootstrap Chameleon Logo

Using Slate to Add Interface for Python Tools

Add a Slate interface for your Python tools just like the UE editor. No C++ code or compilation needed.

Here, we demonstrate how easy it is to create a Slate interface using TAPython's built-in "minimal example."

In this demonstration, we will:

  • Create a standard UE Slate interface
  • Call Python code on button clicks in the interface
  • Use the Python tool to count and display the interface feedback (modify the interface)

In fact, this is the bidirectional communication between the tool logic and the Slate interface.

Minimal Example of TAPython showcase gif

Menu Entry

Just likeAdd a menu item the entry point for tools with an interface is also defined in the MenuConfig.json file.

NOTE
In the following text, we will collectively refer to the tools created with this plugin as Chameleon Tools.

MenuConfig.json

    "OnToolBarChameleon": {
        "items": [
            {
                "name": "Minimal Example",
                "ChameleonTools": "../Python/Example/MinimalExample.json",
                "icon": { "style": "ChameleonStyle", "name": "Flash"}
            }
        ]
    }

In the menu configuration above, instead of using "command" to directly execute a Python command, we use "ChameleonTools" to specify a relative path to a JSON file.

TIP
The relative path here refers to the path relative to the current MenuConfig.json file.

This tool consists of a 30+ line JSON file and a 15-line Python file.

The JSON file defines the appearance of the entire tool interface and will be referred to as the interface file in subsequent documentation.

UI Json File

MinimalExample.json:

{
    "TabLabel": "Example",
    "InitTabSize": [200, 123],
    "InitTabPosition": [680, 150],
    "InitPyCmd": "import Example; chameleon_example = Example.MinimalExample.MinimalExample(%JsonPath)",
    "Root":
    {
        "SVerticalBox":
        {
            "Slots": [
                {
                    "SButton": {
                        "Text": "Click Me",
                        "HAlign": "Center",
                        "VAlign": "Center",
                        "OnClick": "chameleon_example.on_button_click()"
                    }
                },
                {
                    "SEditableTextBox":
                    {
                        "IsReadOnly": true,
                        "Aka": "InfoOutput",
                    }
                }
            ]
        }
    }
}

Parameter Description

  • TabLabel: The title of the tool tab
  • InitTabSize: Controls the size of the tool tab
  • InitTabPosition: Default initial position of the tool
  • InitPyCmd: Import the corresponding Python tool package; create the tool instance chameleon_example;

TIP
(%JsonPath)s a fixed expression that will be automatically replaced with the actual JSON file path at runtime.

Slate Widgets

The contents of the "Root" define the specific element contents of the tool interface. In the example above, we can see that the "SVerticalBox" has two child widgets, an "SButton" for clicking and an "SEditableTextBox" for displaying text

In the "SButton" section, the content of "OnClick" is the Python code to be executed when the button is clicked.

The "Aka" (As known as) in the "SEditableTextBox" section is the "alias" of the "SEditableTextBox" widget. We will use this "alias" to modify its text content later.

TIP
"Aka"is scoped to a single Chameleon tool. In other words, you need to ensure that there are no duplicate "Aka" within a single tool."Aka"

Python Logic

MinimalExample.py

# -*- coding: utf-8 -*-
import unreal
from Utilities.Utils import Singleton

class MinimalExample(metaclass=Singleton):
    def __init__(self, json_path:str):
        self.json_path = json_path
        self.data = unreal.PythonBPLib.get_chameleon_data(self.json_path)
        self.ui_output = "InfoOutput"
        self.click_count = 0

    def on_button_click(self):
        self.click_count += 1
        self.data.set_text(self.ui_output, "Clicked {} time(s)".format(self.click_count))

In the code above:

  • MinimalExampleis a singleton, ensuring only one instance in the editor

  • In the constructor:

  • self.jsonPath variable stores the path to the current tool's interface file
  • self.data variable stores the tool's "ChameleonData instance object"
  • self.ui_output the Aka variable name of the Widget "SEditableTextBox"
  • In the on_button_click method, we use the stored "ChameleonData instance object" (self.data) and its set_text method to modify the text in the widget.

NOTE
The first two lines of the constructor are almost standard for all Chameleon Tools.

Summary

  • The tool's menu item configuration is also in MenuConfig.json.
  • The JSON interface file defines the entire tool's appearance and widgets.
  • The content in the "OnClick" section of the JSON file is the Python code to be executed.
  • Python finds the widget in the UI using the Aka alias defined in the JSON interface.

References

For a more detailed introduction, see here: Tutorial: Create a Rename Tool from Scratch