Substance Painter python API

Hello,

I use python in Maya and want to write some tools in Painter. Anyone got advice on using Substance Painter api with Pycharm.

Thanks :slightly_smiling_face:

Not sure what advice you’re looking for, but writing scripts for Painter in Python is fairly straightforward. I find its integration of Python to be better than Maya, for example. They are continuing to update the API to have more capability. It seems like in the application’s development, they had a split from Javascript to Python, so for a while, although Javascript is deprecated, Python had less capability than the Javascript API. I don’t think this is really true anymore. But there is also a Javascript wrapper in their Python API if there is anything missing.

I’d advise you to refer to the documentation that’s on your local machine where you installed Painter, as it’s been more comprehensive than the python api documentation that is hosted online (now on Adobe’s crap website).

If you have any questions about Painter’s Python API capabilities, feel free to hit me up/post here. Maybe I can help.

3 Likes

Hi AlexJammer,

Thanks for your update.
The documentation on the local machine has been very useful :slightly_smiling_face:.
I do have one question, is it possible to create a new ApplicationMenu. I know how to create a new menu to an existing ApplicationMenu such as a submenu to File.

I thought it would be something like this:

    mymenu = QtWidgets.QMenu()
    mymenu.title = "MyMenu"
    substance_painter.ui.add_menu(mymenu)

But no joy, any help would be great.

Thanks

Yes you can, but the Painter documentation doesn’t make this too clear. You actually need to get the Main Window (Painter API makes this easy with get_main_window()), then get the menuBar() from that, then use addMenu() from there. Would look like this I think:

myMenu = QtWidgets.QMenu()
myMenu.title = "MyMenu"

mainWindow = substance_painter.ui.get_main_window()
mainWindow.menuBar().addMenu(myMenu)

Note that I used addMenu(), which is from the PyQt API, instead of using Substance Painter’s add_menu().

I’m not actually sure why substance_painter.ui.add_menu() exists as I have not successfully used it… Maybe someone else knows.

I hope this helps.

Hello, I tried making a menu called Exports. It’s still failed to show.

import substance_painter

from PySide2 import QtWidgets

plugin_widgets = []


def start_plugin():
    my_menu = QtWidgets.QMenu()
    my_menu.title = "Exports"
    main_window = substance_painter.ui.get_main_window()
    main_window.menuBar().addMenu(my_menu)

    plugin_widgets.append(my_menu)


def close_plugin():
    # Remove all widgets that have been added to the UI
    for widget in plugin_widgets:
        substance_painter.ui.delete_ui_element(widget)

    plugin_widgets.clear()

Any help would be great. Thanks

Yeah I can try. I’ll give you the code I wrote to make the following:
image

Also keep in mind, doing it the way I’m showing you isn’t perfect. Once you have it setup and working, with the script running, if you try to stop the script, it crashes Painter. I think Painter doesn’t actually like it when you do stuff to the Application Menu. But it works as long as you don’t try to shut the script down. Just consider your new menu item on there until you decide to remove or modify the script or something.

Here’s the code I wrote for the screenshot above:

from PySide2 import QtWidgets
import substance_painter.ui

plugin_widgets = []

def start_plugin():
    # Get the application main window.
    mainWindow = substance_painter.ui.get_main_window()

    # Simultaneously create and add your menu to the application menu.
    myMenuMenu = mainWindow.menuBar().addMenu("aMenu")
    plugin_widgets.append(myMenuMenu)

    # Create an action, append it to the removal list, then add it to your menu.
    myAction = QtWidgets.QAction("MyAction")    
    plugin_widgets.append(myAction)
    myMenuMenu.addAction(myAction)

    # Create another action, add it to your menu, and append it to the list, 
    # but with two lines of code this time.
    blahAction = myMenuMenu.addAction("Blah")
    plugin_widgets.append(blahAction)

def close_plugin():
    for widget in plugin_widgets:
        substance_painter.ui.delete_ui_element(widget)
    plugin_widgets.clear()

if __name__ == "__main__":
    start_plugin()
2 Likes

That worked! :slightly_smiling_face:

Here is my version using a signal test.

import substance_painter
from PySide2 import QtWidgets

plugin_widgets = []

def print_test():
    print("Testing 1 2 3 4!")


def start_plugin():
    # Get the application main window.
    main_window = substance_painter.ui.get_main_window()

    # Simultaneously create and add your menu to the application menu.
    fm_exports = main_window.menuBar().addMenu("My Exports")
    myAction = QtWidgets.QAction("Environment Export", triggered = print_test)
    fm_exports.addAction(myAction)

    # Create an action, append it to the removal list, then add it to your menu.
    plugin_widgets.append(myAction)
    plugin_widgets.append(fm_exports)


def close_plugin():
    # Remove all widgets that have been added to the UI
    for widget in plugin_widgets:
        substance_painter.ui.delete_ui_element(widget)

    plugin_widgets.clear()type or paste code here

I can see where I went wrong. I tryed to use a QMenu object instead of a string arg for mainWindow.menuBar().addMenu(“Needs a String Menu name”)

When you mentioned “when you try and shut the script down”. Are you referring to stopping the plugin from the python Application Menu?
When adding tools to the Application Menu I’m adding these modules to the start up menu. This stops artist stopping the plugin. I’m not sure why artist would want to stop a plugin?

I created environment variables SUBSTANCE_PAINTER_PLUGINS_PATH and PYTHONPATH to remotely access my modules from perforce.
When accessing SUBSTANCE_PAINTER_PLUGINS_PATH for my remote startup,plugins and modules directories, startup and plugin work. But modules fails to import. This is why I use my PYTHONPATH to import my personal modules within my plugins. That works.

I notice there is not a lot of threads regarding the Substance Painter Python API within the forum. Hence the large amount of views. :slightly_smiling_face:
I shall share additional post within my findings to help others.

Thanks AlexJammer for all your help! :slightly_smiling_face: :+1:

3 Likes