Getting Started

In order to work on the Mari Tools, you will need a working knowledge of Python. If you are already familiar with Python, please take a moment to review the Coding Style Guide.

First, please follow the instructions for Manual Installation in order to get a working copy of the source.

Making your first plugin using the Mari Tools

Tip

Example source code described here is also available at: ./stkMariTools/tools/examples.

Tip

Please refer to the API Reference if you are unfamiliar with the classes being described here.

To begin making your own Mari plugins and have them be automatically registered using the framework in this toolkit, you will need to perform the following steps:

  1. Subclass MariToolsMenuItem and override the constructor to provide details about the plugin.

    Warning

    Do not duplicate plugin identifiers or action paths! This will cause only one of the plugins to be registered on Mari startup.

  2. Include a actionCommand instance variable that stores a string that will be the command executed when the plugin is executed. This can be anything from running mari commands to opening a full-blown PySide UI. Here we will discuss how to perform the latter.

Example subclass:

class ExampleMenuItem(MariToolsMenuItem):
    """
    This class adds the action.
    """

    def __init__(self):
        """
        The constructor.

        :return:
        """

        # Call base constructor
        super(ExampleMenuItem, self).__init__()

        # Set the class instance in order for the action command to be
        # able to be set in the namespace correctly.
        mari.ExampleMenuItem = self

        # Action item is to be called in the Menu
        self.actionIdentifier = 'Launch Example Plugin'

        # Python command to be run when action is executed from the Menu
        self.actionCommand = 'mari.ExampleMenuItem.doIt()'

        # Path to the action in the Mari Menu
        self.actionPath = 'MainWindow/&Scripts/Examples'

        # Icon to use for the action
        self.actionIcon = 'About'

        # Register the plugin
        self.addMariToolsMenuItem()


    def doIt(self):

        ExampleWidget()
  1. After this, you should subclass MariQWidget in order to create your UI class.
class ExampleWidget(MariWidget):
    """
    This class instantiates a example widget.
    """

    def __init__(self, title='Example Widget'):
        """
        The constructor.

        :return:
        """

        self.closeButton = None

        # Call base constructor
        super( ExampleWidget, self ).__init__(title=title)


    def defineUi(self):
        """
        This method should be overloaded to handle defining the actual UI interface.
        It is run before populateData() and makeConnections().

        :return:
        """

        layout = QtGui.QVBoxLayout()

        checkbox = QtGui.QCheckBox('Show title', self)

        button = QtGui.QPushButton('Push Me')
        self.closeButton = QtGui.QPushButton('Close')

        self.setGeometry(300, 300, 250, 150)

        layout.addWidget(checkbox)
        layout.addWidget(button)
        layout.addWidget(self.closeButton)

        self.widget_holder.setLayout(layout)


    def makeConnections(self, *args, **kwargs):
        """
        Connects the UI controls to callback signals.

        :param args:
        :param kwargs:
        :return:
        """

        # Close button
        self.closeButton.clicked.connect(self.cancelAction)
  1. You should override defineUi in order to define your own widget’s UI. You can either do so by defining the widgets within the method directly or by importing a generated .py file from Qt Designer as well.
  2. makeConnections should be overriden to handle connecting/disconnecting all QSignal/QSlots within the UI itself.
  3. Finally, self.hidePalette and self.cancelAction methods are available as helper methods to destroy the UI, and should be used to connect to UI actions that are intended to close the plugin for palettes/plugins respectively.

Registering the plugin

Once you have written the plugin, you can place it under:

stkMariTools/tools/<path-to-action>

And it should automatically register the next time you launch Mari.

Warning

While it is not strictly required that self.actionPath match the exact folder structure that you have registered the plugin at, it is highly recommended that you do so in order to minimize confusion and make it easier to debug your plugin.

What’s next?

Have a look at the API Reference to see what other plugins are available, what other libraries are available, and to see where best you could help to contribute to the toolkit!