Search code examples
pythonbuttoninstancemaya

Using correct class instance when making multiple instances in succession


Having an issue with my script when I make multiple tabs in a row. I if I make two tabs and then try to edit the first; it changes the second tab and not the first.

import pymel.core as pm
import maya.cmds as cmds
class TabWindow(pm.ui.Window):    
    def __init__(self):
        super(TabWindow, self).__init__()
        self.title = "TabWindow"
        self.tabA = None
        self.tabB = None                      
        self.buildUI()


    def modifySomethingInTabB(self):
        pm.button(label="TestButton", parent=self.tabB)

    def appendJointChain(self, *args):
        print "button pressed"
        self.set_up_Tab()
        self.tool_Tab()



    def fillTabA(self, parent):
        pm.setParent(parent)
        pm.text(label = 'Root Joint Selection', align ='center')
        pm.separator(h=5)
        pm.button(label = 'Add Selector', c=lambda event: self.name_DialogBox())

    def fillTabB(self, parent):    
        pm.setParent(parent)
        pm.text(label = 'FK IK Switch', align ='center')
        pm.separator(h=5)

    def Remove(InstanceName):
        pm.deleteUI(self)


    def buildUI(self):
        tabLayout = None
        children = []
        pm.setUITemplate("DefaultTemplate", pushTemplate=True)
        with pm.columnLayout(adjustableColumn=True,width=300) as cl:
            with pm.tabLayout() as tabLayout:
                for childName in ["My Tab A", "My Tab B"]:
                    with pm.columnLayout(adjustableColumn=True) as cla:
                        children.append((cla, childName))

        self.fillTabA(children[0][0])
        self.fillTabB(children[1][0])
        self.tabA = children[0][0]
        self.tabB = children[1][0]

        pm.tabLayout(tabLayout, edit=True, tabLabel=children)
        pm.setUITemplate("DefaultTemplate", popTemplate=True)      

    def name_DialogBox(self):
        result = cmds.promptDialog(
            title='Rename Object',
            message='Enter Name:',
            button=['OK', 'Cancel'],
            defaultButton='OK',
            cancelButton='Cancel',
            dismissString='Cancel')

        if result == 'OK':
            self.InstanceName = cmds.promptDialog(query=True, text=True)
            ###Create New Tab using text as name####
            self.appendJointChain()
            return self.InstanceName



    def set_up_Tab(self):

        cmds.frameLayout (width = 300, label = self.InstanceName,  collapse = True, collapsable = True, marginWidth = 5, parent = self.tabA);

        self.nametab =cmds.text(label = self.InstanceName, align ='center')

        self.tsL0 =pm.textFieldButtonGrp(ed=False, adj=1,cal=(1,"left"),cw3=(10,100,25), cl3=("left","left","left") , 
                                    buttonLabel='Root   FK', bc= lambda : self.select_joints_afk())
        self.tsL1 = pm.textFieldButtonGrp(ed=False, adj=1,cal=(1,"left"),cw3=(10,100,25), cl3=("left","left","left") , 
                                    buttonLabel='Wrist   IK',bc= lambda : self.select_joints_aikw())
        self.tsL2 = pm.textFieldButtonGrp(ed=False, adj=1,cal=(1,"left"),cw3=(10,100,25), cl3=("left","left","left") , 
                                    buttonLabel='Elbow IK',bc= lambda : self.select_joints_ikpv())

        pm.separator(h=5)
        pm.button( label = 'Remove ' + self.InstanceName, command = lambda :Remove(), width=100)
        pm.separator

        return self.tsL0, self.tsL1, self.tsL2



    def tool_Tab(self):

        cmds.frameLayout (width = 300, label = self.InstanceName,  collapse = True, collapsable = True, marginWidth = 5, parent = self.tabB);
        cmds.separator(h=5)
        self.row=cmds.rowLayout(numberOfColumns=2,width = 300)


        self.IKbutton=cmds.button(label='IK', command = '', width=100)
        self.FKbutton=cmds.button(label='FK', command = '', width=100)
        self.parent=cmds.setParent('..')
        self.row2=cmds.rowLayout(numberOfColumns=2,width = 300)

        self.Fk2IK_Button = pm.button(label='FK 2 IK', command = lambda _: self.fk_2_ik(), width=100)
        self.Ik2FK_Button = pm.button(label='IK 2 FK', command = lambda _: self.ik_2_fk(), width=100)

        self.parent

    def select_joints_afk(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            fkCtrls = cmds.listRelatives(sel, allDescendents=True, type=("transform",'nurbsCurve'))
            self.Fks = [nurbsCurve for nurbsCurve in fkCtrls if nurbsCurve.startswith('FK') & nurbsCurve.endswith('_Ctrl')]
            cmds.textFieldButtonGrp(self.tsL0, edit = True, tx ='' .join(sel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            self.Fks.extend(sel)
            print self.Fks
            return self.Fks,self.tsL0
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )


    def select_joints_aikw(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):

            sel=cmds.ls(selection = True)
            ikwrist = sel
            self.Ikw = [nurbsCurve for nurbsCurve in ikwrist if nurbsCurve.startswith('IK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(self.tsL1, edit = True, tx ='' .join(ikwrist),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            cmds.select(ikwrist)
            print self.Ikw
            return self.Ikw
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', 
                                        dismissString='No' )

    def select_joints_ikpv(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            ikPvsel = sel
            self.ikpv = [nurbsCurve for nurbsCurve in ikPvsel if nurbsCurve.endswith('Pv_Ctrl')]
            cmds.textFieldButtonGrp(self.tsL2, edit = True, tx ='' .join(ikPvsel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))        
            cmds.select(ikPvsel)
            print self.ikpv
            return self.ikpv
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )

    def ik_2_fk(self):

        #import combined selection list
        match_selection = self.Fks + self.Ikw + self.ikpv
        print("List created" + str(match_selection))



    def fk_2_ik(self):
         #import combined selection list
        match_selection = self.Fks + self.Ikw + self.ikpv
        print("List created" + str(match_selection))

tw = TabWindow()
# if pm.window(tw, exists = True):
#     pm.deleteUI(tw)
tw.show()


I'm under the impression that In order to accomplish this I need to have each set of selections be an instance of a class so that I can edit them. With that in mind, I moved the

    def select_joints_afk(self):,    def select_joints_aikw(self):, &   def select_joints_ikpv(self):

into a Create selectionChains class like so..

class Create_Selection_Chains():

    def __init__(self, name ,Fks, Ikw, ikpv):
        self.name=name
        self.Fks = Fks
        self.Ikw = Ikw
        self.ikpv = ikpv
        print  Fks + Ikw + ikpv


    def select_joints_afk(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            fkCtrls = cmds.listRelatives(sel, allDescendents=True, type=("transform",'nurbsCurve'))
            self.Fks = [nurbsCurve for nurbsCurve in fkCtrls if nurbsCurve.startswith('FK') & nurbsCurve.endswith('_Ctrl')]
            cmds.textFieldButtonGrp(TabWindow().tsL0, edit = True, tx ='' .join(sel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            self.Fks.extend(sel)
            print self.Fks
            return self.Fks 
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )

    def select_joints_aikw(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):

            sel=cmds.ls(selection = True)
            ikwrist = sel
            self.Ikw = [nurbsCurve for nurbsCurve in ikwrist if nurbsCurve.startswith('IK') & nurbsCurve.endswith('Ctrl')]
            cmds.textFieldButtonGrp(Set_up_Tab().tsL1, edit = True, tx ='' .join(ikwrist),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))
            cmds.select(ikwrist)
            print self.Ikw
            return self.Ikw
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], defaultButton='Ok', 
                                        dismissString='No' )

    def select_joints_ikpv(self):
        if cmds.ls(selection = True,type=("transform",'nurbsCurve')):
            sel = cmds.ls(sl=True)
            ikPvsel = sel
            self.ikpv = [nurbsCurve for nurbsCurve in ikPvsel if nurbsCurve.endswith('Pv_Ctrl')]
            cmds.textFieldButtonGrp(self.tsL2, edit = True, tx ='' .join(ikPvsel),buttonLabel='IK OK',backgroundColor = (.5,.8,.2))        
            cmds.select(ikPvsel)
            print self.ikpv
            return self.ikpv
        else:
            text = cmds.confirmDialog( title='Error', message='Must select joint', button=['OK'], 
                                        defaultButton='Ok', dismissString='No' )

& the instance is created In TabWindow Class method def appendJointChain(self, *args)::

self.joint_chain_select = Create_Selection_Chains( self, "foo", "bar", "baz")

I've made several attempts at this (shown above in Create_Selection_Chains class) but I can't seem to get it right.


# Error: AttributeError: file <maya console> line 136: 'TabWindow' object has no attribute 'tsL0' #
# Error: NameError: file <maya console> line 150: global name 'Set_up_Tab' is not defined #
# Error: AttributeError: file <maya console> line 163: Create_Selection_Chains instance has no attribute 'tsL2' #

I think I might need to have the tabs I create in the UI be either thier own class or part of Create_Selection_Chains class but I'm really unsure at this point. Could someone explain what is going on and how I might be able to solve this?


Solution

  • It is a bit difficult to give you some advice since your code is somewhat chaotic. Since you are creating one interface and you use pymel anyway I recommend to keep everything within one single class and build everyting in this class. e.g. you want to create a window with two tabs could work this way:

    class TabWindow(pm.ui.Window):
        def __init__(self):
            super(TabWindow, self).__init__()
            self.title = "TabWindow"
            self.tabA = None
            self.tabB = None
            self.buildUI()
    
        def createSelecttionChain(self):
            pass
    
        def modifySomethingInTabB(self):
            pm.button(label="TestButton", parent=self.tabB)
    
        def pushButton(self, *args):
            print "button pressed"
            self.modifySomethingInTabB()
    
        def fillTabA(self, parent):
            pm.setParent(parent)
            pm.button(label="PushMe", c=self.pushButton)
    
        def buildUI(self):
            tabLayout = None
            children = []
            pm.setUITemplate("DefaultTemplate", pushTemplate=True)
            with pm.columnLayout(adjustableColumn=True) as cl:
                with pm.tabLayout() as tabLayout:
                    for childName in ["My Tab A", "My Tab B"]:
                        with pm.columnLayout(adjustableColumn=True) as cla:
                            children.append((cla, childName))
    
            self.fillTabA(children[0][0])
            self.tabA = children[0][0]
            self.tabB = children[1][0]
    
            pm.tabLayout(tabLayout, edit=True, tabLabel=children)
            pm.setUITemplate("DefaultTemplate", popTemplate=True)      
    
    tw = TabWindow()
    tw.show()
    

    Then you can add your tools step by step. This way the code is much better readable and much better to maintain. And errors are easier to find.