Knob mapping

The core idea behind smartEdit is to provide custom PySide widgets that drive the Nuke internal knobs.

Keep in mind that smartEdit does not offer custom widgets to map all Nuke internal knobs. But it covers most of these. The following section provides information to create additional knob mappings.

All knob mapping classes are contained inside modules of the package’s widgets Python package. All of these modules contain a class with the same name of their modules. These classes inherit from smartEdit.widgets.base.KnobBase. The KnobBase takes the Nuke knob to drive as argument.

The KnobBase base class is an abstract class that provides the base building blocks to make a knob mapping happen. Each class inheriting from this base needs to implement the abstract methods create_widgets, create_layouts and create_signals. In order to kep things simple, we combined the UI and controller into one class in order to not increase complexity by creating dedicated views and controllers. The setup method can be overwritten to set up widget’s states.

smartEdit also provides functionality to expose or hide advanced widget states. For that, you can use the advanced member. As an example see the smartEdit.widgets.slider.Slider class and have a look at the classes create_layouts method that adds certain widgets to the custom knob mapping class only when the setting’s advanced_widgets is turned on.

The actual mapping takes then place in smartEdit.knob_mapper.MAP where we tell Nuke which custom widgets to map to which knobs. To get the underlying Nuke knob type you can always print the type of a knob, e.g:

print type(nuke.selectedNode()["size"])

This prints the underlying knob type for the size knob of the current node selection.

Example - CheckBox

In order to fully understand the above structure let’s have a look at a basic example knob mapping class - The CheckBox. This widget maps a Nuke checkbox knob. This are covered as nuke.Boolean_Knob and nuke.Disable_Knob. These knobs are for example used as a node’s disable checkbox which is a node that is present on almost any node.

_images/knob_mapping_checkbox.jpg

The mapping class for the knobs can be found in smartEdit.widgets.checkbox.Checkbox. It looks like the following:

# Import local modules
from smartEdit.widgets.base import KnobBase

class Checkbox(KnobBase):
    """Checkbox to enable or disable a state."""

    def create_widgets(self):
        """Create widgets."""
        self.label = QtWidgets.QLabel(self.knob.name())
        self.checkbox = QtWidgets.QCheckBox()

    def setup_widgets(self):
        """Setup widgets."""
        self.checkbox.setChecked(self.knob.value())

    def create_layouts(self):
        """Create layouts."""
        self.layout_main.addWidget(self.label)
        self.layout_main.addWidget(self.checkbox)
        self.layout_main.addStretch()

    def create_signals(self):
        """Create signals."""
        self.checkbox.stateChanged.connect(lambda: self.update())

    def update(self):
        """Update the node's dropdown to the currently selected value."""
        self.knob.setValue(self.checkbox.isChecked())

The Checkbox class inherits fro the KnobBase and implements the above stated abstract methods. The widget contains a label and a checkbox. Although a checkbox contains a label by default, we use a separate label to ensure the label is located left to the checkbox. We overwrite the setup_widgets method to set up the checkboxe’s checked state to be driven by the checked state of the classes knob member which holds a reference to the Nuke knob checkbox that we want to drive. We overwrite the create_layouts method to set up the layout and set up the create_signals to create a signal which will drive changes of the widget’s checkbox to update the Nuke knob that we are referencing. The actual value change of the Nuke knob happens then in the update method.

This is a basic example that shows the way to map custom widgets to Nuke knobs. A more advanced example can be seen in smartEdit.widgets.slider.Slider.