You may have used a gizmo in the past where toggling a checkbox enables/disables a set of knobs, or choosing a certain value from a Pulldown Choice will hide or show another set of knobs. What wizardry is this??? At least that’s what I asked myself when embarking on my first gizmo-creating frenzy…
After searching the web, I came across many threads in many forums explaining this mysterious thing called “knobChanged”, accompanied by a load of copy/pasted code to explain how to use it. With my limited knowledge of Python at the time, I had no idea what any of it meant. I just wished there was someone who posted what I needed and that was it. If this describes you right now, you’re in luck!
knobChanged is an invisible knob that holds code to execute any time you change a specified knob on a selected node. Nuke’s user guide does a great job at explaining it, although I’d like to provide a simplified practical example (without defining functions) for those who might not be Python-savvy.
Here is the Python you’re looking for, and how to use it…
Important Note: You have to compress the following code down to one single line for Nuke to understand & run it. I’ll explain this further at the end of the post.
nuke.selectedNode().knob('knobChanged').setValue( 'n = nuke.thisNode() k = nuke.thisKnob() if k.name() == "effectOnly" and k.value() == 1: n["mergeType"].setEnabled(False) else: n["mergeType"].setEnabled(True)')
The first line says “Find the knobChanged knob on the selected node, then assign it the following code”:
Create a variable n, which is equal to thisNode
Create a variable k, which is equal to thisKnob
If there is a knob in the selected node called effectOnly, and if the effectOnly knob has a value of 1, then:
>>>> set the mergeType knob in the selected node to False
>>>> (which will grey it out, so you can’t change the value)
Although, if the effectOnly knob has a value other than 1, then:
>>>> set the mergeType knob in the selected node to True
>>>> (which will enable it, so you can adjust the values again)
You have to define what effectOnly and mergeType is depending on the names of your knobs in your gizmo, but hopefully this clearly outlines what is happening.
Instead of disabling/enabling a knob, what if you want to hide and show it? You just have to change setEnabled from the above example to setVisible, like so:
nuke.selectedNode().knob('knobChanged').setValue( 'n = nuke.thisNode() k = nuke.thisKnob() if k.name() == "effectOnly" and k.value() == 1: n["mergeType"].setVisible(False) else: n["mergeType"].setVisible(True)')
To compress this back down into one line so that Nuke doesn’t get confused and processes everything correctly, all you have to do is replace the linebreaks with \n, and every indent should be a single space ” “.
nuke.selectedNode().knob('knobChanged').setValue('n = nuke.thisNode()\nk = nuke.thisKnob()\nif k.name() == "effectOnly" and k.value() == 1:\n n["mergeType"].setVisible(False)\nelse:\n n["mergeType"].setVisible(True)')
I find this method is the simplest and easiest way to understand the concept as it’s all happening in one process. Although, Nuke’s user manual suggests you define a function to hold your code, and then use
nuke.addKnobChanged(function) to assign it.
UPDATE: Adrian Pueyo has released a super useful tool to make scripting hidden callback knobs with python a lot faster & more intuitive. You can download KnobScripter here, or watch a tutorial on how it works here.