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. If you find a knob missing feel free to add it, it’s not that difficult to do so. The following section will help you with that and 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.
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.