-2

all i am trying is to is add more items to dictionary and populate with second button if necessary!!! everything goes fine, on running code from maya script editor by clicking on the blue play button but if i import this script import funtest funtest.main()

the window loads up fine but i get error on clicking either of the buttons ... So please tell me why is their a difference between executing the code from script editor and the other one by importing..

it shouild be same or if it is what is wrong with my logic ?

import maya.cmds as cmds
dic={}
print("dictionary is empty",dic)
def main():
    inst=btnUI()
    inst.create()


class btnUI(object):
    def __init__(self, winName="winTheWindow"):
        self.winTitle = "The Window"
        self.winName = winName

    def create(self):
        if cmds.window(self.winName, exists=True):
            cmds.deleteUI(self.winName)
        dic['item1']='item1value'
        dic['item2']='item2value'

        cmds.window(self.winName, title=self.winTitle)
        self.mainCol = cmds.columnLayout( adjustableColumn=True )
        self.btnA = cmds.button( label='Press Me - External Func',c='outsideFunc(dic)' )
        self.btnb = cmds.button( label='Populate more items',c='populateDic()' )
        cmds.showWindow( self.winName )
        cmds.window(self.winName, edit=True, widthHeight=[250,75])



def populateDic():
    dic['item3']='item3value'
    dic['item4']='item4value'
    dic['item5']='item5value'

def outsideFunc(dicItems):
    print("Outside function, called from inside a class function")
    print(dicItems)

if __name__ == '__main__':
    main()
Ciasto piekarz
  • 7,853
  • 18
  • 101
  • 197

1 Answers1

0

It's because the resolution of your c arguments to cmds.button() are happening in another namespace. It appears there are several ways to solve it, but I recommend following the more Pythonic way:

from functools import partial
self.btnA = cmds.button( label='Press Me - External Func',
                         c=partial(outsideFunc, dic))
self.btnb = cmds.button( label='Populate more items',c=populateDic)

For button A, I'm using partial to help pass dic to outsideFunc, so that the resultant function produced by partial doesn't require any arguments (it's been pre-loaded with the dic argument).

For button B, this is unnecessary, as it doesn't take any arguments. So we just give it the name of the function to call. Note the lack of quotes. Python will resolve this in the correct namespace, and will work as expected.

BTW, this page appears to be helpful and talks about command callbacks: http://www.luma-pictures.com/tools/pymel/docs/1.0/ui.html

UPDATE: Buttons pass an argument to their callback, so you need to wrap it:

from functools import partial
self.btnA = cmds.button( label='Press Me - External Func',
                         c=lambda arg: outsideFunc(dic))
self.btnb = cmds.button( label='Populate more items',c=lambda arg: populateDic())

This creates a couple of anonymous functions that throw away the argument (since you don't need it).

John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
  • thanks mate, i never attempted pymel but i guess i should give it a try .. so i accomplished it with outsideFunc((dicItems,inst): same way with populateDic(inst), does that mean that inst is the function itself , i.e. 0th item ? – Ciasto piekarz Sep 15 '12 at 11:49
  • I updated the post. Apparently, buttons pass in an argument. You can use a lambda function to throw it away. Unfortunately, I don't know anything about Maya, so what it's passing in, I don't know. My educated guess is it's state information, or something representing the button object (kind of like `self`). But I don't know for sure. – John Szakmeister Sep 15 '12 at 11:51