Pymel Class help

Any Pymel experts around? Executing this results in an error or two, “unbound method must be called with … instance as a first argument (got nothing instead)”. What am I missing?


from pymel.core import *
from pymel.all import *
import pymel.core.uitypes
class simpleClassA():
    
    variable = "we're printing!"
    
    def aCommand(*args):
        print variable
            
    def simpleUI(*args):
        if pymel.core.uitypes.Window.exists('simpleUI'):
            deleteUI('simpleUI')
        window_simpleUI = window('simpleUI', title = 'test window')
        layout = formLayout()
        button_press_me = button(label = 'press me', command = Callback(simpleClassA.aCommand))
        window_simpleUI.show()
        
testObj = simpleClassA()
testObj.simpleUI()


#try this:
import pymel.core as pm

class simpleClassA():
    
    variable = "we're printing!"
    WINDOW_NAME = 'simpleUI'
    
    def aCommand(self, *args):
        print self.variable
            
    def simpleUI(self, *args):
        if pm.window(self.WINDOW_NAME, exists=True):
            pm.deleteUI(self.WINDOW_NAME)
        window_simpleUI = pm.window(self.WINDOW_NAME, title = 'test window')
        layout = pm.formLayout()
        button_press_me = pm.button(label = 'press me', command = pm.Callback(self.aCommand))
        window_simpleUI.show()
        
testObj = simpleClassA()
testObj.simpleUI()

Also, your imports are rendundant. from pymel.all import * covers it. I would actually recommend keeping it simpler than that and use import pymel.core as pm (or some other alias). Most of the time you won’t need alot of the stuff in the other modules imported by all, and as a point of personal preference, i prefer to just make function calls for consistency. When doing UI work, the function calls return class instances anyway (for the most part), so you’re not really losing anything and it keeps your code clean.

Patrick:
1- When you get an error, give us the entire error and traceback.
2- Never use ‘from foo import *’.
3- See Seth’s fixed code.

4- Profit. :slight_smile:

Thanks Seth! Modifying the code as you did is incredibly helpful.

Alright, another question!! I want an attribute object, and was hoping this would work:

attr_object = someNode.addAttr(…)

but addAttr doesn’t return anything. So, I have to refer to the attribute name directly, which makes the ATTR_NAME variable a bit useless…

any input?


import pymel.core as pm
class someClass():
    
    someNode = None
    someAttr = None
    
    ATTR_NAME = 'the_attribute'
    ATTR_VALUE = 'the_value'
    
    def createTestNode(self, *args):
        self.someNode = pm.sets()
        self.someNode.addAttr(self.ATTR_NAME, dataType = "string")

        self.someAttr = pm.PyNode(self.someNode.the_attribute)
        #here!  Is this the best way?
        #I'd like to use ATTR_NAME, not "the_attribute"

        self.someAttr.set(self.ATTR_VALUE)        

thinger = someClass()
thinger.createTestNode()

I’ve noticed that too. You could cast it as a PyNode directly after its creation:

self.ATTR = pm.Attribute('.'.join([self.someNode.name(), self.ATTR_NAME]) )

can you use …

self.someAttr = self.someNode.attr(ATTR_NAME)

Its been a long day though, so i may be completely mis-reading your post!

self.someAttr = getattr(self.someNode, self.ATTR_NAME)?

Just to clarify first question, this error:

“… instance as a first argument (got nothing instead).”

Always means you’ve forgotten ‘self’ as the mandatory first argument when defining a class’ method.

If you use an IDE like Eclipse with PyDev, it will flag this missing argument (and many other simple mistakes) before you finish writing the line. Just a suggestion.