文本框前缀替换查询

0 投票
2 回答
1134 浏览
提问于 2025-04-18 05:40

我正在忙着为我的绑定工具创建一个功能,这个功能可以镜像关节并替换前缀。关节的镜像(包括行为和方向)已经可以正常工作,但当我在两个文本框中进行搜索和替换时却出现了错误。场景中关节的前缀要么是R_,要么是L_,我想用其他内容替换它们。

错误信息是:NameError: name searchFor is not defined。奇怪的是,我实际上创建了一个叫searchFor的变量,还有一个叫replaceWith的变量。下面是相关代码:

import maya.cmds as cmds 

child2 = cmds.gridLayout( cw = self.size[ 0 ] / 2 - 10, nc = 2 )
cmds.text( l = ' Mirror Joints', al = 'left', font = "boldLabelFont" ) 
cmds.separator( style = 'none' )
searchFor = cmds.textFieldGrp( tx = 'Search for...' )
replaceWith = cmds.textFieldGrp( tx = 'Replace with...' )  

cmds.button( label = 'Mirror Orientation',
             command = "cmds.mirrorJoint( cmds.ls( sl = True ), 
             mirrorYZ = True, 
             mirrorBehavior = False, 
             searchReplace = cmds.textFieldGrp( searchFor, q = True, tx = True),
             cmds.textFieldGrp( replaceWith, q = True, tx = True )" ) 

cmds.button( label = 'Mirror Behaviour',
             command = "cmds.mirrorJoint( cmds.ls ( sl = True ), 
             mirrorYZ = True, 
             mirrorBehavior = True )" ) 

这段代码是用户界面的一部分,其他功能是从另一个模块调用的。难道我需要在用户界面模块中创建一个包含mirrorJoint命令的函数吗?还是说这样做是可行的?

想要更好地查看代码,可以访问这个链接: https://dl.dropboxusercontent.com/u/545575/python.zip

2 个回答

0

是的,你需要一个函数。把命令写成字符串的方式只有在所有引用的对象都在全局空间时才有效(这并不推荐,所以字符串命令也不推荐)。

创建一个函数最简单的方法是使用lambda:

cmds.button(   
    label='Mirror Orientation',
    command=lambda *_: cmds.mirrorJoint(cmds.ls (sl=True), mirrorYZ=True, mirrorBehavior=False, searchReplace=(cmds.textFieldGrp(searchFor, q=True, tx=True),cmds.textFieldGrp(replaceWith, q=True, tx=True)))
)

Lambda可以创建一个没有名字的函数,而*_则允许你传入任意数量的临时参数。当这个函数被调用时,它会去调用之前在字符串命令中的cmds.mirrorJoint

0

你用一个字符串来调用函数,这个字符串会在全局范围内被解释,就好像你直接在监听器里输入了一样;在你的函数外面,'searchFor'是不存在的。

这里有一个关于maya如何处理回调命令的参考资料:http://techartsurvival.blogspot.com/2014/04/maya-callbacks-cheat-sheet.html

MHLester的例子可以实现你想要的效果,但你需要注意闭包的问题。lambda表达式会从它被定义的范围中继承变量——但是是在这个范围关闭的时候,而不是它被定义的时候;这可能会导致一些意外的结果。例如,如果你尝试这样做:

def test():
    w = cmds.window()
    cmds.columnLayout()    
    example = 1
    cmds.button("test", c= lambda *_:  sys.stdout.write( "example: %i" % example ) )
    example = 4
    cmds.showWindow(w)

点击按钮时会打印出'4',尽管看起来应该是'1'。

撰写回答