因此我按下时会尝试输出按钮的标签(按钮标签应该替换buttonNumber功能打印中的XXX)。我不知道如何从按钮中检索标签数据以输出。有什么想法吗?提前致谢
import maya.cmds as mc
def buttonNumber(*args):
print 'Button XXX was pressed'
def openWindow():
if mc.window('windowTest', ex=True):
mc.deleteUI('windowTest', window=True)
mc.window('windowTest', title='', s=True, resizeToFitChildren = True,)
mc.rowColumnLayout(numberOfColumns = 3, columnWidth = [ (1, 150), (2, 150), (3, 150)])
mc.button(label='1', command=buttonNumber)
mc.button(label='2', command=buttonNumber)
mc.button(label='3', command=buttonNumber)
mc.button(label='4', command=buttonNumber)
mc.button(label='5', command=buttonNumber)
mc.button(label='6', command=buttonNumber)
mc.button(label='7', command=buttonNumber)
mc.button(label='8', command=buttonNumber)
mc.button(label='9', command=buttonNumber)
mc.showWindow('windowTest')
openWindow()
答案 0 :(得分:2)
我建议你在stackoverflow上阅读关于Partial的其他帖子(注意还有另一种方法用Lambda)
我没有测试下面的代码(我这里没有maya,但你会得到这个想法)
import maya.cmds as mc
from functools import partial
def buttonNumber(label, *args):
print('Button {0:03d} was pressed'.format(label))
def openWindow():
if mc.window('windowTest', ex=True):
mc.deleteUI('windowTest', window=True)
mc.window('windowTest', title='', s=True, resizeToFitChildren = True,)
mc.rowColumnLayout(numberOfColumns = 3, columnWidth = [ (1, 150), (2, 150), (3, 150)])
mc.button(label='1', command=partial(buttonNumber, 1))
mc.showWindow('windowTest')
openWindow()
答案 1 :(得分:2)
正如@DeWeeny所说,您可以使用functools.partial
对象将值绑定到按钮命令。您也可以使用函数工厂为这个非常简单的应用程序执行此操作,或者使用可记住的类来记住每个实例的值。
def make_callback(value):
def inner_callback(_):
print value, "was clicked"
return inner_callback
w = cmds.window()
c = cmds.columnLayout()
for n in range(9):
cmds.button( label = str(n), command = make_callback(n))
cmds.showWindow(w)
唯一的微妙之处是inner_callback
有一个未使用的参数(_
),它需要它,因为按钮回调总是触发一个无用的参数
如果数据比函数工厂示例
更复杂或需要更多计算,这将非常有用class NumberCallback(object):
def __init__(self, id):
self.id =
def __call__(self, _):
print self.id, "was clicked"
w = cmds.window()
c = cmds.columnLayout()
for n in range(9):
cmds.button( label = str(n), command = NumberCallback(n))
cmds.showWindow(w)
这在功能上是相同的但是如果你必须做一些更复杂的行为,一个类会使它整洁
您可以在网上找到使用lambda
进行操作的建议。对于很多很棒的应用程序 - 但不要在循环中执行。如果你这样做:
def clicked(num):
print num, "was clicked"
w = cmds.window()
c = cmds.columnLayout()
for n in range(9):
cmds.button( label = str(n), command = lambda p: clicked(n))
cmds.showWindow(w)
所有按钮都会响应
8 was clicked
因为lambda会全部捕获循环中的最后一个变量,而这并不是你想要的。
答案 2 :(得分:1)
我前段时间在博客上做了一点提醒,能够测试所有不同的本机Maya UI使用命令的方式,并快速测试它们:
每个案例都给出了将变量作为参数传递给这些函数的示例。因为有时你必须能够。 总的来说,我完全推荐使用 functools.partial ,它只提供优于其他的优势(如果你忘了PySide)。
def function(*args):
print args
cmds.textFieldGrp(text, edit=True, text=str(args))
variable = 'Variable'
width = [1, 250]
align = [1, 'left']
window = cmds.window(title='UI and commands arguments.')
cmds.columnLayout()
cmds.textFieldGrp(label="\"function()\"", changeCommand="function()", columnWidth=width, columnAlign=align)
cmds.textFieldGrp(label="function", changeCommand=function, columnWidth=width, columnAlign=align)
cmds.textFieldGrp(label="\"function(variable)\"", changeCommand="function(variable)", columnWidth=width, columnAlign=align)
cmds.textFieldGrp(label="lambda x: function(variable)", changeCommand=lambda x: function(variable), columnWidth=width, columnAlign=align)
cmds.separator(style="double", height=20)
import functools
cmds.textFieldGrp(changeCommand=functools.partial(function), label='functools.partial(function)', columnWidth=width, columnAlign=align)
cmds.textFieldGrp(changeCommand=functools.partial(function, variable), label='functools.partial(function, variable)', columnWidth=width, columnAlign=align)
cmds.separator(style="single", height=20)
import pymel.core
cmds.textFieldGrp(changeCommand=pymel.core.Callback(function), label='pymel.core.Callback(function)', columnWidth=width, columnAlign=align)
cmds.textFieldGrp(changeCommand=pymel.core.CallbackWithArgs(function), label='pymel.core.CallbackWithArgs(function)', columnWidth=width, columnAlign=align)
cmds.textFieldGrp(changeCommand=pymel.core.CallbackWithArgs(function, variable), label='pymel.core.CallbackWithArgs(function, variable)', columnWidth=width, columnAlign=align)
cmds.separator(style="single", height=20)
text = cmds.textFieldGrp(label='RESULT: ', text='', width=500)
cmds.showWindow()
因为它不是在考虑课堂的情况下制作的,所以当你在课堂上时,某些方法根本不起作用。
class MayaUI():
def __init__(self):
self.variable = 'Variable'
self.width = [1, 250]
self.align = [1, 'left']
self.window = cmds.window(title='UI and commands arguments.')
cmds.columnLayout()
cmds.textFieldGrp(label="\"self.function()\"", changeCommand="self.function()", columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(label="self.function", changeCommand=self.function, columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(label="\"self.function(self.variable)\"", changeCommand="self.function(self.variable)", columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(label="lambda x: self.function(self.variable)", changeCommand=lambda x: self.function(self.variable), columnWidth=self.width, columnAlign=self.align)
cmds.separator(style="double", height=20)
import functools
cmds.textFieldGrp(changeCommand=functools.partial(self.function), label='functools.partial(self.function)', columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(changeCommand=functools.partial(self.function, self.variable), label='functools.partial(self.function, self.variable)', columnWidth=self.width, columnAlign=self.align)
cmds.separator(style="single", height=20)
import pymel.core
cmds.textFieldGrp(changeCommand=pymel.core.Callback(self.function), label='pymel.core.Callback(self.function)', columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(changeCommand=pymel.core.CallbackWithArgs(self.function), label='pymel.core.CallbackWithArgs(self.function)', columnWidth=self.width, columnAlign=self.align)
cmds.textFieldGrp(changeCommand=pymel.core.CallbackWithArgs(self.function, self.variable), label='pymel.core.CallbackWithArgs(self.function, self.variable)', columnWidth=self.width, columnAlign=self.align)
# A bit more complicated
_map = {'textFieldGrp': lambda arg:cmds.textFieldGrp(arg, query=True, text=True)}
_com = lambda *args:args[0](self.variable, _map[args[1]](args[2]))
cmds.textFieldGrp('textfieldName', changeCommand=pymel.core.Callback(_com, self.function, 'textFieldGrp', 'textfieldName'), label="pymel.core.Callback(_com, self.function, 'textFieldGrp', 'textfieldName') + lambdas", columnWidth=self.width, columnAlign=self.align)
cmds.separator(style="single", height=20)
self.text = cmds.textFieldGrp(label='RESULT: ', text='', width=500)
cmds.showWindow()
def function(self, *args):
print args
cmds.textFieldGrp(self.text, edit=True, text=str(args))
MayaUI()
答案 3 :(得分:0)
这是我的代码,可以满足您的需求。
我没有硬编码每个按钮标签的参数以在按钮创建时传递给函数,而是将按钮的对象名称传递给函数。这样,可以随时查询按钮的所有属性(包括标签)。
为了表明这一点,我做了一个随机函数,生成随机字母数字字符串并将它们分配给按钮标签。
它会让你娱乐30秒。试试吧!
import maya.cmds as mc
import random, string
from functools import partial
def randomButtonTest():
buttonsList = []
numButtons = 5
winName = 'randomButtonWin'
winWidth = 250
statusTfgName = 'myStatusTfg'
buttonLabelLength = 10
def generateRandomLabel(myLength):
# generates a random string of characters of myLength
randomCandidatesList = list(string.ascii_letters + string.digits)
random.shuffle(randomCandidatesList)
randomCandidatesStr = ''.join(randomCandidatesList)
return ''.join([randomCandidatesStr[random.randint(0,len(randomCandidatesStr)-1)] for x in range(myLength)])
def reportButtonLabel(whichButton, *args):
buttonLabel = mc.button(whichButton, q=True, label=True)
print 'reportButtonLabel: clicked - %s' % buttonLabel
mc.textFieldGrp(statusTfgName, e=True, text=buttonLabel)
return
def randomiseButtonClicked(*args):
mc.textFieldGrp(statusTfgName, e=True, text='')
for thisButton in buttonsList:
currentLabel = mc.button(thisButton, q=True, label=True)
newLabel = '%s: %s' %(currentLabel.split(':')[0], generateRandomLabel(buttonLabelLength))
mc.button(thisButton, e=True, label=newLabel)
return
# build UI
if mc.window(winName, exists=True):
mc.deleteUI(winName)
mc.window(winName, title='Randon Button Labels', w=winWidth )
mc.columnLayout(w=winWidth)
# create numButtons number of buttons
for buttonId in range(numButtons):
buttonsList.append(mc.button(label='button %i:'%buttonId, w=winWidth ))
mc.button(buttonsList[-1], e=True, command=partial(reportButtonLabel, buttonsList[-1]))
mc.text(label='')
mc.textFieldGrp(statusTfgName, label='Button clicked', w=winWidth, columnWidth2=[winWidth*0.3, winWidth*0.65])
mc.text(label='')
mc.button('Randomise labels', w=winWidth, command=randomiseButtonClicked)
randomiseButtonClicked()
mc.window(winName, e=True, w=winWidth, h=150, resizeToFitChildren=True)
mc.showWindow(winName)
randomButtonTest()