Search code examples
pythonmayaautodesk

Code wont work on startup and connectAttr textfield question


Ok, so I'm working on a simple demo similar to one of my other questions, it's quite simple, simply run the script, load an object into A node, load an object into B node, hit "connect nodes" and the translate of your 2 items will be connected.

Atleast, thats what I wish would happen. Instead I keep getting "# Error: name 'SetSource' is not defined" or any of my other commands saying "Not defined" strangely enough I can temporarily fix this if I just go to "c = SetSource" or any of the other commands, cut them from the code, re run the window, then paste them back in place and they will work: but this is a hassle and I just want it to work right on startup.

The second problem is when I load things into the textfield and try to connect them with the Connect Nodes button, I get errors saying "# Error: The source attribute 'Object you loaded into the A Node textField' cannot be found."

There are a couple things I already tried, for example: the startup problem I tried wrapping the buttons and text fields in their own little "def" category, I named it ui(): and posted ui() at the end of the code, and this makes it run fine on startup except when I ran the script it refused to load anything into the textfields

for the connect command to connect the translates I tried putting def connect(attr, *args) instead of just def_connect() but if I try making attr an *args command it just gets ignored and I'm told "attr not defined"

I'm kindof at the end of my rope here. I'm compiling everything I made in other scripts to make one master script for building helper joints in rigging and this double textfield is the last thing standing in my way.

import maya.cmds as cmds

if cmds.window("dumWin", exists =True):
    cmds.deleteUI("dumWin")

window = cmds.window("dumWin",title='DS selection connector demo')
column = cmds.columnLayout(adj=True)
cmds.showWindow(window)



sld_textFldA = cmds.textField('sld_surfaceText1', width =240)
load_button = cmds.button( label='Load A Node', c = SetSource)

sld_textFldB = cmds.textField('sld_surfaceText2', width =240)
load_button = cmds.button( label='Load B Node', c = SetTarget)

load_button = cmds.button( label='Connect Nodes', c = connect)


def SetSource(_):
    sel = cmds.ls(selection=True)
    cmds.textField(sld_textFldA, edit=True, text=sel[0])

def SetTarget(_):
    sel = cmds.ls(selection=True)
    cmds.textField(sld_textFldB, edit=True, text=sel[0])

def connect(_):
    cmds.connectAttr( source + '.', target + '.', f=True)

My expected result is to have the code just work on startup without calling my defs "undefined" and to just have the connect nodes connect the translates


Solution

  • The reason you're getting the error Error: name 'SetSource' is not defined is because you defined it after your button creation. It needs to evaluate before you set your button's command function otherwise it's not be able to find it. The solution here is simple, and it's to move your 3 functions on top.

    As for your connect function, you are using variables source and target, but those aren't initialized anywhere within the scope of that function, so it fails. Instead you need to query the textField for their current text. Since the user can also type freely in them, it'll be a good idea to include a simple check to see if the nodes we get from both textField actually exist.

    import maya.cmds as cmds
    
    
    def SetSource(_):
        sel = cmds.ls(selection=True)
        cmds.textField(sld_textFldA, edit=True, text=sel[0])
    
    
    def SetTarget(_):
        sel = cmds.ls(selection=True)
        cmds.textField(sld_textFldB, edit=True, text=sel[0])
    
    
    def connect(_):
        obj_a = cmds.textField(sld_textFldA, q=True, text=True)
        obj_b = cmds.textField(sld_textFldB, q=True, text=True)
    
        if not cmds.objExists(obj_a) or not cmds.objExists(obj_b):
            raise RuntimeError("Unable to find objects in the scene.")
    
        cmds.connectAttr(obj_a + '.translate', obj_b + '.translate', f=True)
    
    
    if cmds.window("dumWin", exists =True):
        cmds.deleteUI("dumWin")
    
    window = cmds.window("dumWin",title='DS selection connector demo')
    column = cmds.columnLayout(adj=True)
    cmds.showWindow(window)
    
    sld_textFldA = cmds.textField('sld_surfaceText1', width =240)
    load_button = cmds.button( label='Load A Node', c = SetSource)
    
    sld_textFldB = cmds.textField('sld_surfaceText2', width =240)
    load_button = cmds.button( label='Load B Node', c = SetTarget)
    
    load_button = cmds.button( label='Connect Nodes', c = connect)