As a little sidenote on using lambdas I've found that when executing a
procedure through a GUI using lambdas that includes undo-worthy Maya calls,
Maya is logging each call seperately in the undo array which can be a pain
if you are doing a lot of different things during that procedure.

With some help from Ofer I've found the only workaround is to use a callback
object somewhat similar to the one implimented into pymel, but executing
it's content through maya.mel.eval().
My callback object looks like this:


*class Callback(object):

    _callData = None

    @staticmethod
    def _doCall():
        (func, args, kwargs) = Callback._callData
        Callback._callData = func(*args, **kwargs)

    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs

    def __call__(self, *args):
        Callback._callData = (self.func, self.args, self.kwargs)
        if __name__ != '__main__':
            mm.eval('python("' + __name__ + '.Callback._doCall()")')
        else:
            mm.eval('python("Callback._doCall()")')
        return Callback._callData
*


the if-else in __call__() could maybe be replaced by:
*mm.eval('python("import sys; sys.modules["%s"].Callback._doCall()")' %
__name__)
*
but I haven't tested yet, so I didn't wanna post it.

If you are not doing any undo-ish maya calls though, this issue isn't
visible.




On Fri, Jan 9, 2009 at 3:35 AM, John Creson <[email protected]> wrote:

> Also, you could put a query into the function you are calling that finds
> the list for itself without relying on the button click to pass in the list.
> The query in the function could look into a string variable on a node in
> the scene, or query an environment variable, or query a text field control
> on the gui window.
>
>
>
> On Thu, Jan 8, 2009 at 6:41 PM, Chris G <[email protected]> wrote:
>
>> Also you can use functools.partial for this :
>>
>> from functools import partial
>>
>> def someDef(theList, someParameter):
>>     ...
>>
>> cmds.button(command=partial(someDef, someList, someParameter=2))
>>
>>
>>
>> On Thu, Jan 8, 2009 at 2:24 AM, Ofer Koren <[email protected]> wrote:
>>
>>> Another way, somewhat similar to lambdas but without those 'buggy'
>>> behaviours, is to use a 'callback' object:
>>> class Callback:
>>>      def __init__(self,func,*args,**kwargs):
>>>         self.func = func
>>>         self.args = args
>>>         self.kwargs = kwargs
>>>     def __call__(self,*args, **kwargs):
>>>         return self.func(*self.args, **self.kwargs)
>>>
>>>
>>> def someDef(theList, someParameter):
>>>        ....
>>>
>>> cmds.button(command = Callback(someDef, someList, someParameter = 2))
>>>
>>>
>>>
>>> (FYI - Pymel has a more robust version of this object which supports
>>> Undo:  from pymel import Callback)
>>>
>>>
>>> On Wed, Jan 7, 2009 at 7:44 PM, Matthew Chapman <[email protected]>wrote:
>>>
>>>>        This is a common mistake, the way you have written this python
>>>> will call 'someDef(someList)' and pass its results to named argument
>>>> 'command'. There are a couple ways to get this to work the way you would
>>>> like. My personal choice is this
>>>>
>>>> # Define a function that can take any named or unnamed arguments
>>>> # the * tells python to put any unnamed arguments into a list
>>>> # the ** tell python to put any names arguments into a dictionary
>>>>
>>>> def someDef(  *args, **kwargs ):
>>>>     # call function or have inline code that creates someList
>>>>     someList = getSomeList()
>>>>     print someList
>>>>
>>>> def buildUI():
>>>>      # <insert all stuff that defines window>
>>>>
>>>>      # create button and pass the function it self to the argument
>>>>      # command=someDef() # will pass the result where as
>>>>      # command=someDef   # passes the actual function to the argument
>>>>
>>>>>  cmds.button(command=someDef)
>>>>
>>>>
>>>>       If you really want to pass  in data in the call as its being
>>>> defined you should use a lambda. A lambda is an unamed function. I have
>>>> heard of lambdas being buggy in certain instances because of how they are
>>>> defined and stored in memory in modules like pyqt. Here is how you could
>>>> write is.
>>>>
>>>> def buildUI():
>>>>     # ' ' ' ' ' ' ' ' ' ' '  \/
>>>>
>>>>>  cmds.button(command=lambda *args : someDef(someList ))
>>>>
>>>>
>>>> If you new the namespace of you function you could always pass it as a
>>>> string to 'command'.
>>>>
>>>> def buildUI():
>>>>     # ' ' ' ' ' ' ' ' ' ' '  \/
>>>>
>>>>>  cmds.button(command="myModule.someDef([%s] )" % str(someList))
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>>
>>>
>>> - Ofer
>>> www.mrbroken.com
>>>
>>>
>>>
>>
>>
>>
>> >>
>>


-- 
JAKOB WELNER
   _____________
   Animator | R&D
   jakob.welner.dk



-- 
JAKOB WELNER
   _____________
   Animator | R&D
   jakob.welner.dk

--~--~---------~--~----~------------~-------~--~----~
Yours,
Maya-Python Club Team.
-~----------~----~----~----~------~----~------~--~---

Reply via email to