Dynamically add/remove knobs from gizmos

Categories Gizmos, Nuke, Python, Quick Tip

Some gizmos dynamically hide/show a number of knobs with the KnobChanged python callback. This is a good option to keep your gizmo’s UI clean, but can start to get very heavy when you have too many knobs to handle, and too many nodes inside your gizmo.

Instead, it can be cleaner to use Python Script Buttons to add/remove knobs/nodes from your gizmo to keep things fast, neat and tidy.

I whipped up the following example node, which you can download here, to see how this works.

The main consideration is we have to be able to give created knobs a unique name, in order to preserve the links between all the related elements. I’ve done this via the use of a hidden integer knob, which I’ve named knob_count. Any time a user clicks the Add a Multiply button, the value of knob_count increases by 1. Then, we use that value to append the name of any knob we create.

Outside of this, we’re simply adding/finding/removing knobs and internal Multiply nodes.

### Start below this function...

# We have to define this function first, so that we can add it to the "remove" button.
def remove_knobs():    
    # Get the my_knob and remove button.
    knob_name = nuke.thisKnob().name()[:-7]
    knob_name_remove = nuke.thisKnob()
    # Delete them!
    # Dive into the group and find the node with the label that matches the knobs that were
    # just removed. DELETE THE NODE!
    for node in nuke.allNodes():
        if knob_name in node.knob('label').value():

### Here is how to dynamically add/remove nodes.

# Add controls to the node...
count = nuke.thisNode().knob('knob_count').setValue(nuke.thisNode().knob('knob_count').value()+1)
knob_counter = str(int(nuke.thisNode().knob('knob_count').value()))

knob_name = "my_knob_"+knob_counter

# Multiply knob
nuke.thisNode().addKnob(nuke.Double_Knob(knob_name, "Multiply_"+knob_counter))
# Remove button -- this holds the fucntino we defined at the start.
nuke.thisNode().addKnob(nuke.PyScript_Knob(knob_name+"_remove", "remove", "remove_knobs()"))

# There is a child/parent relationship when diving inside of nodes.
# By default, when we write python, it executes in "root", or the "parent" nuke script...
# If we want to execute code inside a group, we have to "begin" working inside of it.

# We want to create nodes between the input and output nodes. We can take advantage of inbuilt functionality,
# and select the last node before the Output node, so when the next node is created, it will be the last in the stack.

# Create the node!
multiply_node = nuke.createNode('Multiply')

# Expression-link to the knob we just created.
multiply_node.knob('label').setValue("Linked to: "+"my_knob_"+knob_counter)

# End working in the group.