PDA

View Full Version : Python:Values in function and GUI


nerv789
12-20-2007, 09:35 AM
Hi there,
Got a question.
I've been trying to do this for ages.
I want to enter text and pass it to variable and then to other function.

This code actually works when the first potion is not defined as function, but as soon as I give it as function, it says textValue is undefine.
I'm guessing it's problem with function memory getting wiped after it's been executed and not avairable when I do stuff in GUI.

How can I make it so it retains data?

thanks

def batch():
window=mc.window()
mc.columnLayout(width=520, adjustableColumn=True)
mc.frameLayout(label='Batch', borderStyle='etchedOut')

##Get what's on textfield and pass it to variable
mc.rowColumnLayout( numberOfColumns=3, columnWidth=[(1, 100), (2, 300),(3, 100)])
mc.text( label='Data Path within \n Project Direcotry' )
pathDir=mc.textField(tx='textures/')
textValue = mc.textField( pathDir,q=1,tx=1)
mc.textField(pathDir, e=True, cc=('textValue=mc.textField(pathDir, q=1, tx=1'))
mc.button(label="Run", command=('replaceDir(textValue)'))
mc.setParent(window)
mc.showWindow(window)
def replaceDir(path):
print path

r4inm4ker
12-21-2007, 01:10 AM
try this:

tmpStr = 'replaceDir("'+textValue+'")'
mc.button(label="Run", command= tmpStr)

Chadrik
12-29-2007, 06:15 AM
def batch():
window=mc.window()
mc.columnLayout(width=520, adjustableColumn=True)
mc.frameLayout(label='Batch', borderStyle='etchedOut')

##Get what's on textfield and pass it to variable
mc.rowColumnLayout( numberOfColumns=3, columnWidth=[(1, 100), (2, 300),(3, 100)])
mc.text( label='Data Path within \n Project Direcotry' )
pathDir=mc.textField(tx='textures/')
mc.button(label="Run", command=lambda: replaceDir( mc.textField( pathDir,q=1,tx=1) )
mc.setParent(window)
mc.showWindow(window)
def replaceDir(path):
print path


the lambda command allows you to create an "unbound" function on the fly, so to speak, without having to predefine it. when the button is pressed it executes it's callback command, the lambda function, which takes the value of the textField query at the time of the button press and passes it on to the replaceDir function.

i tend to use function object as my callbacks instead of strings because it is a little more versatile, but it depends on what you're trying to do. my example will pass on the current value at the time of the button press, whereas the string formatting option provided by r4inm4ker will pass on the value at the time the GUI was created.

-chad

nerv789
01-07-2008, 02:08 AM
r4inm4ker, chad,
Thank you very much for your help.

I was able to make it work with r4inm4ker's solution.

However, I'm really interested in chad's solution as well.
I'm tyring to get it to work but seems like it's not going right.
When I copied and pasted the code, it ran into error, so I added quotation mark around the command and closing parenthesis to make it run.
When I ran it, it gave me something like "# Result: <function <lambda> at 0x0BBC9630> # " which looks like memory address.
Have I done something wrong? or this is how it should be and there is some way to retrive the string value from this memory address?

Again, thank you for your help.
I really appriciate it.
-Yuta
This is code I ran

def batch():
window=mc.window()
mc.columnLayout(width=520, adjustableColumn=True)
mc.frameLayout(label='Batch', borderStyle='etchedOut')

##Get what's on textfield and pass it to variable
mc.rowColumnLayout( numberOfColumns=3, columnWidth=[(1, 100), (2, 300),(3, 100)])
mc.text( label='Data Path within \n Project Direcotry' )
pathDir=mc.textField(tx='textures/')
mc.button(label="Run", command='lambda: replaceDir( mc.textField( pathDir,q=1,tx=1))' )
mc.setParent(window)
mc.showWindow(window)
def replaceDir(path):
print path

batch()

Chadrik
01-07-2008, 07:43 AM
sorry, i had two typos in my original. i forgot a closing parentheses and i forgot to give lambda an argument.


import maya.cmds as mc
def batch():
window=mc.window()
mc.columnLayout(width=520, adjustableColumn=True)
mc.frameLayout(label='Batch', borderStyle='etchedOut')

##Get what's on textfield and pass it to variable
mc.rowColumnLayout( numberOfColumns=3, columnWidth=[(1, 100), (2, 300),(3, 100)])
mc.text( label='Data Path within \n Project Direcotry' )
pathDir=mc.textField(tx='textures/')
mc.button(label="Run", command=lambda *args: replaceDir( mc.textField( pathDir,q=1,tx=1) ) )
mc.setParent(window)
mc.showWindow(window)
def replaceDir(path):
print path

batch()


ok, so here's a little more clarification on what's going on here. lambda is just a function written in one line. the following code would also work (assuming i don't make any more typos):


import maya.cmds as mc

def batch():
window=mc.window()
mc.columnLayout(width=520, adjustableColumn=True)
mc.frameLayout(label='Batch', borderStyle='etchedOut')

##Get what's on textfield and pass it to variable
mc.rowColumnLayout( numberOfColumns=3, columnWidth=[(1, 100), (2, 300),(3, 100)])
mc.text( label='Data Path within \n Project Direcotry' )
pathDir=mc.textField(tx='textures/')

# create the callback function
def buttonCallback( *args ):
replaceDir( mc.textField( pathDir,q=1,tx=1) )

mc.button(label="Run", command=buttonCallback )
mc.setParent(window)
mc.showWindow(window)
def replaceDir(path):
print path

batch()


you can see that the lambda is a bit neater. if you are coming from a mel background, the fact that i just declared a function within a function may have just blown your mind, but it's perfectly valid. i had to do it this way so that the callback function had access to the pathDir variable.

now, getting back to business. the callback command can either be a string or an actual callable object. notice in the above example that there are no quotes around buttonCallback. buttonCallback is variable that holds a function object. everything in python is an object -- strings, function, classes. if i had passed 'buttonCallback' i would have been just passing the *name* of the function, but without the quotes i am passing the actual function object itself.

so now that my button has a function to call when it is pressed, what next? well, when the button is pressed, whether you like it or not, maya is going to pass some argument to your callback function. this is to reproduce the shorthand syntax available in mel for getting a value from a ui element at the time of execution. in mel it looked like this:

radioButtonGrp -nrb 2 -cc "myscript #1 #2";

the #1 and #2 represent the values of the two radiobuttons when the changeCommand occurred. in mel they were optional, but in python they are always passed. different ui elements have differing numbers of arguments that are passed, some none at all. that's where *args comes into play. this is getting a bit beyond the scope of the discussion, but this is a syntax that allows a variable number of arguments to be accepted by a function:


def myfunc( *args ): print args
myfunc( 1 )
(1,)
myfunc( 'one', 2.2, 3)
('one', 2.2, 3)


for some reason, the button command provides an argument to our callback. by adding the * in front of args, i allow the lambda to accept any number of arguments, but i don't use them: i just call our replaceDir function. i always use this syntax with my callback commands, so that i don't need to know how many arguments they are passing, since most of the time i don't want to use them anyway

so, i hope that this helped and didn't just add further confusion. let me know if anything needs to be explained in greater detail.

-chad

nerv789
01-08-2008, 07:05 AM
chad,

Thank you so much for very detailed explanation!

I really appriciate all the time you spent.

I think I understood it all and hope to use it to make central GUI for my scripts.
I was just having trouble with similar situation.

Again, thank you so much!

katisss
09-11-2008, 03:52 PM
Very useful. But i am still getting in trouble when i want to pass
a variable to the function.
I dynamically create a number of checkboxes and buttons and i want each to pass a
path or layoutname in their command. How would i do that?
EDIT
http://groups.google.com/group/python_inside_maya/browse_thread/thread/c539f74c9b39e61c#

CGTalk Moderation
09-11-2008, 03:52 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.