PDA

View Full Version : Scope in Maya?


EightBit
03-08-2011, 03:04 AM
I've encountered an interesting problem:
Say I have 2 UI based tools and both have a Layout element w/the same name, Maya will throw an error when I try to load the 2nd script:
ie.
cmds.scrollLayout('sliders_scroll',w=400)
# RuntimeError: Object's name 'sliders_scroll' is not unique. #

I would've thought that each instance of the scrollLayout would be held in it's own scope, IE:
windowA.sliders_scroll and windowB.sliders_scroll

Is there a standard programming approach to avoid this problem?
Thanks.

dbsmith
03-08-2011, 03:39 AM
Indeed you are correct.
Maya stores exact absolute paths to layouts, thus when you call:
cmds.scrollLayout('sliders_scroll',w=400)
maya doesn't know which of the 2 layouts you mean.

Check out commands such as:
maya.cmds.lsUI(controlLayouts=True, long=True)

To avoid this, we never refer to controls and UI elements by names. Instead, at creation time, we store their names that get returned in a dictionary. Eg
self.uiDict['SeatWidth'] = maya.cmds.floatField('seat', value=1.0, precision=3)

Thus the unique name of the control is stored, not an ambiguous short name like 'seat'

EightBit
03-08-2011, 05:22 AM
Hmm.
But wouldn't you still encounter the error if you tried to use the same name for UI elements in different windows?

uiron
03-08-2011, 10:29 AM
Hmm.
But wouldn't you still encounter the error if you tried to use the same name for UI elements in different windows?

using dbsmith's advice, UI creation method returns full path, therefore, it will always be unique. it's like using a full path to a DAG node.

ginodauri
03-08-2011, 10:37 AM
You obviously don't understand scopes in python.
You probably switched from mel , and continue using mel logic.
This is why , i first red python book and then made switch.

Python namespace refer to variables and not strings.

So when you have file named foo , and for example have code in there "myVar=0"

You can do:
import foo
print foo.myVar

This means that variable myVar is in namespace of file foo.

What i do is to define my namespace for ui in script for example:

def myUI() : pass

and than i can attach names of controll in there as attributes for example:

def createUI():
myUI.win=mc.window()
myUI.col=mc.columnLayout()
etc.

Another solution is to use classes , which use similar in sense of namespace but have more power.

uiron
03-08-2011, 11:01 AM
You obviously don't understand scopes in python.
You probably switched from mel , and continue using mel logic.
This is why , i first red python book and then made switch.

i know python inside out, no need to go that offensive. control names have NOTHING to do with python namespaces. Controls *are* identified by strings, either by short name, like "button1", by partial name, like "layout1|button1", or by full name, like "window1|layout1|sublayout2|button1". using full name will guarantee that you refer to the exact control you want.

now combine that with your knowledge about PYTHON namespaces, where each class can store it's values in it's own namespace. here's an example of a button that puts a random value into a text box, but each opened window does that for it's own controls:


from maya import cmds
import random
class RandomizerDialog:
def __init__(self):
self.editBox = None

def show(self):
wind = cmds.window(width=100,height=100)
cmds.columnLayout(width=100,adjustableColumn=1)
cmds.button(label='Randomize', command=self.execButtonPushed)
# remember full text field name
self.editBox = cmds.textField('randomValue')
cmds.showWindow(wind)

def execButtonPushed(self,*args):
# use remembered text field name to set value for it
cmds.textField(self.editBox,e=True, text=str(random.random()))

# create and open three windows
for i in range(3):
RandomizerDialog().show()


pythonic enough for you?

ginodauri
03-08-2011, 11:34 AM
uiron this comment:
"""
You obviously don't understand scopes in python.
You probably switched from mel , and continue using mel logic.
This is why , i first red python book and then made switch.
"""

was about EightBit original question , where it is obvious that he don't understand scopes in python.

I don't understand why you thought that i was talking to you?

uiron
03-08-2011, 01:06 PM
I don't understand why you thought that i was talking to you?

I don't know, I'm embarrassed now:]

EightBit
03-08-2011, 02:49 PM
Hey, I didn't try to hide the fact that I'm having trouble understanding scope - look at the title of the post...
Thanks so much for the answers.
uiron:
I appreciate the example, I'm not a hard core coder so examples work best for me. A couple followup questions:
Is it pretty standard to put the UI in a class? Do you do that w/vars also?
What is the function of the __init__ def?
Note that when I execute your code, the first 2 instances of the window are huge, the third obeys is smaller, but still larger than the defined width and height.
Thanks again.

uiron
03-08-2011, 03:20 PM
Is it pretty standard to put the UI in a class? Do you do that w/vars also?

you can put anything into a class as long as it makes sense. e.g., if you create just one class for whole bunch of various purposes and name it "TheClass", it doesn't make sense. If you create a class who's main purpose is to construct a UI window, provide UI response handlers - it makes sense:]
for larger applications, it's best to separate UI and execution logic into different classes, just to keep UI construction, button click handlers and other ui related stuff separate from actual work that's being done (e.g., creating an Ik/Fk rig). I don't see a problem of bundling UI and actual work into one class if it's a relatively small script.


What is the function of the __init__ def?

That's class constructor. When you create class instance, this method gets called. I don't do any particular work in it, except for defining one instance variable.


Note that when I execute your code, the first 2 instances of the window are huge, the third obeys is smaller, but still larger than the defined width and height.
Thanks again.

It's just because maya stores window preferences. Names of these new windows' are probably "window1", "window5" or smth, and if previously you had created windows with such names (knowingly or not), then maya just stored their positions already.
to get the size specified by ui, you need to delete window preferences from maya. just add this code after window creation:


if cmds.windowPref(wind,q=True,exists=True):
cmds.windowPref(wind,remove=True)

EightBit
03-08-2011, 03:39 PM
Thanks a lot.
I need to study up on using classes in Python.

CGTalk Moderation
03-08-2011, 03:39 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.