top of page

BATCH EDIT

  • jnietomonco
  • Feb 6, 2023
  • 1 min read

Updated: Feb 8, 2023

This is another code I wrote when I changed from one studio to a different one. It allows you to change values in multiple nodes at the same time, no matter their class. I have it set on my menu.py to work when I press ctrl+e.


ree

The code will make a list of the knobs in the nodes you have selected and show them in a window. You have multiple options for different kind of nodes and operations.


The different options are :

  • Knobs: This will show a list of knobs you can change, and the rest of the options will adapt to your selection, for example tile_color

  • Multiple knobs?: Check this to edit multiple knobs

  • New value is: You can select between Value and Expression and the field below will adapt to your selection

  • Enter value: To add your new value or expression to apply to the knob selected

  • Multiple boxes?: This is for whenever you want to change knobs that have more than one value, like Position or Scale for example. It will change the Enter value field and show 4 independent fields instead of just one

Expand Batch Edit Code


import nuke
import types
import nukescripts

def batchEdit():
    selectedNodes = nuke.selectedNodes()
    selected = nuke.selectedNode()
    allKnobs = selected.knobs().keys()
    knobsList = sorted(allKnobs)
    print "All the knobs available are %s" % knobsList

    # Python Panel
    class BatchEditPanel(nukescripts.PythonPanel):
        def __init__(self, node):
            nukescripts.PythonPanel.__init__(self, 'Batch Edit')
            self.rpNode = node
            # CREATE KNOBS
            # Text knob works like this: nuke.Text_Knob(name, label, Text)
            self.text = nuke.Text_Knob('', ('%s nodes selected' % len(selectedNodes)), ' ')
            self.knobType = nuke.Enumeration_Knob('knobs', 'Knobs', knobsList)
            self.knobType.setTooltip('Choose the knob you want to change')
            self.moreKnobs = nuke.Boolean_Knob('moreKnobs', 'Multiple knobs?', None)
            self.moreKnobs.setTooltip('Mark this box if you want to change more than one knob')
            self.valueType = nuke.Enumeration_Knob('valueType', 'New value is:', ['Value', 'Expression'])
            self.valueType.setTooltip('Is the new value an expression?')
            self.enterValue = nuke.String_Knob('enterValue', 'Enter value', '')
            self.multipleValues = nuke.BBox_Knob('multipleValues', 'Values')
            self.multipleValues.setVisible(False)
            self.tileColor = nuke.ColorChip_Knob('tileColor', 'Tile Color')
            self.tileColor.setVisible(False)
            self.tileColor.setFlag(nuke.STARTLINE)
            self.multipleBoxes = nuke.Boolean_Knob('multipleBoxes', 'Multiple boxes?', None)
            self.multipleBoxes.setTooltip('Replaces the single "Enter value" box for four different boxes')
            self.multipleBoxes.setFlag(nuke.STARTLINE)

            # ADD KNOBS
            self.addKnob(self.text)
            self.addKnob(nuke.Text_Knob('', '', ''))
            self.addKnob(self.knobType)
            self.addKnob(self.moreKnobs)
            self.addKnob(self.valueType)
            self.addKnob(self.enterValue)
            self.addKnob(self.multipleValues)
            self.addKnob(self.tileColor)
            self.addKnob(self.multipleBoxes)

        # Create a callback for whenever a knob is changed (any knob!)
        def knobChanged(self, knob):
            # We check if the knob that was changed was the valueType, multipleBoxes, or Tile Color was chosen.
            if knob == self.valueType:
                if self.valueType.getValue() == 0.0:
                    self.enterValue.setLabel('Enter value')
                    self.enterValue.setTooltip('value')
                    self.multipleBoxes.clearFlag(nuke.INVISIBLE)
                    self.multipleBoxes.setVisible(True)
                    if self.multipleBoxes.value() == True:
                        self.multipleValues.clearFlag(nuke.INVISIBLE)
                        self.multipleValues.setVisible(True)
                        self.enterValue.setFlag(nuke.INVISIBLE)
                        self.enterValue.setVisible(False)
                    elif self.multipleBoxes.value() == False:
                        self.multipleValues.setFlag(nuke.INVISIBLE)
                        self.multipleValues.setVisible(False)
                        self.enterValue.clearFlag(nuke.INVISIBLE)
                        self.enterValue.setVisible(True)
                elif self.valueType.getValue() == 1.0:
                    self.enterValue.setLabel('Enter expression')
                    self.enterValue.setTooltip('expression')
                    self.enterValue.clearFlag(nuke.INVISIBLE)
                    self.enterValue.setVisible(True)
                    self.multipleBoxes.setFlag(nuke.INVISIBLE)
                    self.multipleBoxes.setVisible(False)
                    if self.multipleBoxes.value() == True:
                        self.multipleValues.clearFlag(nuke.INVISIBLE)
                        self.multipleValues.setVisible(True)
                    elif self.multipleBoxes.value() == False:
                        self.multipleValues.setFlag(nuke.INVISIBLE)
                        self.multipleValues.setVisible(False)
                        self.enterValue.clearFlag(nuke.INVISIBLE)
                        self.enterValue.setVisible(True)
                    self.multipleValues.setFlag(nuke.INVISIBLE)
                    self.multipleValues.setVisible(False)
            if knob == self.multipleBoxes:
                if self.multipleBoxes.value() == False:
                    self.multipleValues.setFlag(nuke.INVISIBLE)
                    self.multipleValues.setVisible(False)
                    self.enterValue.clearFlag(nuke.INVISIBLE)
                    self.enterValue.setVisible(True)
                if self.multipleBoxes.value() == True:
                    self.multipleValues.clearFlag(nuke.INVISIBLE)
                    self.multipleValues.setVisible(True)
                    self.enterValue.setFlag(nuke.INVISIBLE)
                    self.enterValue.setVisible(False)
            if knob == self.knobType:
                if self.knobType.value() == 'tile_color':
                    self.valueType.setFlag(nuke.INVISIBLE)
                    self.valueType.setVisible(False)
                    self.multipleValues.setFlag(nuke.INVISIBLE)
                    self.multipleValues.setVisible(False)
                    self.enterValue.setFlag(nuke.INVISIBLE)
                    self.enterValue.setVisible(False)
                    self.multipleBoxes.setFlag(nuke.INVISIBLE)
                    self.multipleBoxes.setVisible(False)
                    self.tileColor.clearFlag(nuke.INVISIBLE)
                    self.tileColor.setVisible(True)
                else:
                    self.valueType.clearFlag(nuke.INVISIBLE)
                    self.valueType.setVisible(True)
                    if self.valueType.getValue() == 0.0:
                        self.multipleBoxes.clearFlag(nuke.INVISIBLE)
                        self.multipleBoxes.setVisible(True)
                        self.enterValue.setLabel('Enter value')
                        self.enterValue.setTooltip('value')
                        self.multipleBoxes.clearFlag(nuke.INVISIBLE)
                        self.multipleBoxes.setVisible(True)
                        if self.multipleBoxes.value() == True:
                            self.multipleValues.clearFlag(nuke.INVISIBLE)
                            self.multipleValues.setVisible(True)
                            self.enterValue.setFlag(nuke.INVISIBLE)
                            self.enterValue.setVisible(False)
                        elif self.multipleBoxes.value() == False:
                            self.multipleValues.setFlag(nuke.INVISIBLE)
                            self.multipleValues.setVisible(False)
                            self.enterValue.clearFlag(nuke.INVISIBLE)
                            self.enterValue.setVisible(True)
                    elif self.valueType.getValue() == 1.0:
                        self.multipleBoxes.setFlag(nuke.INVISIBLE)
                        self.multipleBoxes.setVisible(False)
                        self.enterValue.setLabel('Enter expression')
                        self.enterValue.setTooltip('expression')
                        self.enterValue.clearFlag(nuke.INVISIBLE)
                        self.enterValue.setVisible(True)
                    self.tileColor.setFlag(nuke.INVISIBLE)
                    self.tileColor.setVisible(False)

    panel = BatchEditPanel(nuke.selectedNode())
    panel.setMinimumSize(550, 50)
    if panel.showModalDialog():
        # Assign panel values just if we clic OK.
        chosenKnob = panel.knobType.value()
        print 'The knob you choose to change is: %s' % chosenKnob
        newValue = panel.enterValue.value()
        print 'New value is %s ' % newValue
        tileColorValue = panel.tileColor.value()
        expressionField = (panel.valueType.value() == 'Expression')
        multiple = (panel.multipleBoxes.value() == True)
        newMultipleValues = panel.multipleValues.value()
        newBatchEdit = panel.moreKnobs.value()
        allSelected = nuke.selectedNodes()

        if expressionField == True:
            print 'Expression field detected. Expression is: %s' % newValue
            for i in allSelected:
                try:
                    i[chosenKnob].setExpression(newValue)
                except:
                    nuke.message('Error. Could not set expression')
        elif expressionField == False:
            print 'No expression detected.'
            for i in allSelected:
                knobType = type(i.knob(chosenKnob).value())
                print knobType
                if knobType == int:
                    if chosenKnob == 'tile_color':
                        i.knob(chosenKnob).setValue(int(tileColorValue))
                    else:
                        i.knob(chosenKnob).setValue(int(newValue))
                elif knobType == float:
                    i.knob(chosenKnob).setValue(float(newValue))
                elif knobType == bool:
                    if newValue == '0' or newValue == 'False' or newValue == 'false' or newValue == '0.0' or float(
                            newValue) < 1:
                        i.knob(chosenKnob).setValue(False)
                    elif newValue == '1' or newValue == 'True' or newValue == 'true' or newValue == '1.0' or (
                            int(round(float(newValue))) >= 1):
                        i.knob(chosenKnob).setValue(True)

                elif knobType == str:
                    i.knob(chosenKnob).setValue(str(newValue))
                elif knobType == unicode:
                    i.knob(chosenKnob).setValue(unicode(newValue))
                elif knobType == list:
                    listValues = i.knob(chosenKnob).getValue()
                    listOriginalElements = len(listValues)
                    while True:
                        if len(listValues) < 4:
                            listValues.append(0.0)
                        if len(listValues) >= 4:
                            break
                    R = newMultipleValues[0]
                    G = newMultipleValues[1]
                    B = newMultipleValues[2]
                    A = newMultipleValues[3]
                    listValues[0] = (float(R))
                    listValues[1] = (float(G))
                    listValues[2] = (float(B))
                    listValues[3] = (float(A))
                    while True:
                        if listOriginalElements < 4:
                            del listValues[-1]
                        if len(listValues) == listOriginalElements:
                            break
                    i.knob(chosenKnob).setValue(listValues)
                elif knobType == tuple:
                    if multiple == False:
                        i.knob(chosenKnob).setValue(float(newValue))
                    if multiple == True:
                        tupleValues = i.knob(chosenKnob).getValue()
                        tupleList = list(tupleValues)
                        tupleListOriginalElements = len(tupleList)
                        while True:
                            if len(tupleList) < 4:
                                tupleList.append(0.0)
                            if len(tupleList) >= 4:
                                break
                        newX = newMultipleValues[0]
                        newY = newMultipleValues[1]
                        newR = newMultipleValues[2]
                        newT = newMultipleValues[3]
                        tupleList[0] = (float(newX))
                        tupleList[1] = (float(newY))
                        tupleList[2] = (float(newR))
                        tupleList[3] = (float(newT))
                        while True:
                            if tupleListOriginalElements < 4:
                                del tupleList[-1]
                            if len(tupleList) == tupleListOriginalElements:
                                break
                        tupleValues = tupleList
                        i.knob(chosenKnob).setValue(tupleValues)
        if knobType == bool and float(newValue) < 1 and float(newValue) != 0:
            nuke.message('Boolean value needs to be 0 or 1. Input value smaller than 1. Setting value to 0.')
        if knobType == bool and float(newValue) > 1:
            nuke.message('Boolean value needs to be 0 or 1. Input value greater than 1. Setting value to 1.')
        if newBatchEdit == True:
            batchEdit()

def batchEditCheck():
    # Check selected nodes number and knobs
    selectedNodes = nuke.selectedNodes()
    if len(selectedNodes) == 0:
        nuke.message('You have to select at least one node.')
    if len(selectedNodes) == 1:
        print 'You selected %s nodes' % len(selectedNodes)
        batchEdit()
    if len(selectedNodes) > 1:
        # Check if selected nodes classes are the same.
        classesList = []

        for i in selectedNodes:
            nodeClasses = i.Class()
            classesList.append(nodeClasses)

        if not all(x == classesList[0] for x in classesList):
            if nuke.ask(
                    "The nodes selected don't have the same class and some knobs will not be the same. Do you want to continue?"):
                batchEdit()
        else:
            batchEdit()



Javier Nieto Moncó © 2025

  • linkedin
  • vimeo
  • generic-social-link
bottom of page