Search code examples
maya

Maya Python static class function scope


I have some trouble getting my static class to work. There is something I am missing about the scope of functions within a class. If called the script gives me following error:

     NameError: global name 'disableCostumFrames' is not defined #



import maya.cmds as cmds
from functools import partial

class Blast:
    def createWindow():
        # Todo:
        #    hanldes the gui for the user

        windowID = 'window'

        if cmds.window(windowID, exists = True):
            cmds.deleteUI('window')

        window = cmds.window(windowID, title="Blast", iconName='Blast', widthHeight=(400, 200) )
        cmds.frameLayout( label='')

        cmds.rowColumnLayout( numberOfColumns=4, columnWidth=[(1, 100),(3, 100)] )
        cmds.text( label='Start: ' )
        global Blast_startFrame
        Blast_startFrame = cmds.textField( enable = False)
        cmds.text( label=' End: ' )
        global Blast_endFrame
        Blast_endFrame = cmds.textField( enable = False)
        cmds.setParent('..')

        cmds.rowColumnLayout( numberOfColumns=2, columnWidth=[(1, 100), (2, 100)] )
        cmds.radioCollection()
        #cmds.radioButton( label='Full', select = True, onCommand= partial(disableCostumFrames, Blast_startFrame, Blast_endFrame ) )
        #cmds.radioButton( label='Costum', onCommand= partial(enableCostumFrames, Blast_startFrame, Blast_endFrame ) )
        cmds.setParent('..')

        cmds.rowColumnLayout( numberOfColumns=1, columnWidth=[(1, 400), (2, 100)] )   
        cmds.button( label='Playblast' ,command= 'createPlayblast')
        cmds.setParent('..')

        cmds.showWindow( window )

        return Blast_startFrame, Blast_endFrame

    def main():
        createWindow()

    def enableCostumFrames(Blast_startFrame, Blast_endFrame, *args):
        cmds.textField(Blast_startFrame, edit=True, enable=True)
        cmds.textField(Blast_endFrame, edit=True, enable=True)


    def disableCostumFrames(Blast_startFrame, Blast_endFrame, *args):
        cmds.textField(Blast_startFrame, edit=True, text="", enable=False)
        cmds.textField(Blast_endFrame, edit=True, text="", enable=False)

How do I need to define these functions within the class? I am calling the module like that:

import sys
Dir = 'c:/Blast'
if Dir not in sys.path:
    sys.path.append(Dir)
try: reload(Blast_v011)
except: import Blast_v011

Blast_v011.Blast()

maybe iam doing something wrong on this side? Appreciated any help.


Solution

  • In this case you need to add a self reference to all of the methods in your class. The usual python class looks like this:

    class MyClass(object):
    
       def __init__(self):
           self.variable = 123
    
       def some_method(self):
           print "my variable = ", self.variable
    
       def some_other_method(self):
           if self.variable > 1:
              self.some_method()
    

    The self reference in the member functions is how you get at class member variables and other functions -- it's python's way of referring to what other languages call this.

    Instance methods can only be called on an instance (it's the instance that gets passed in as self). You can make a method that is called on the class itself -- rather than any particular instance of the class -- using the @classmethod decorator. Classmethods also take an argument, but instead of self it's a reference to the class. You use it the same way to get variables defined at the class level, which are shared by all copies of the class:

    class HasShared(object):
        shared = 99
    
        @classmethod
        def a_class_method(cls):
            print cls.shared
    

    (You can mix and match class and instance methods in the same class).

    You can also make static methods using the @staticmethod decorator. These don't get a default argument at all:

     class NotPythonic(object):
    
         @staticmethod
         def needs_no_args():
             print "call me as NotPythonic.needs_no_args()"
    

    In Python we tend to avoid this formula, since you can get a static method by just creating a function in a module without making a class to hold them. For the example code you posted, I'd probably just make a conventional class using instance methods, since your functions need the names of the gui widgets to be able to actually ask them questions.