So, after a lot of trial and error I have this code that creates a UI that lets a user enter name, which creates a set of widgets in two tabs. One for selecting joint chains and one that will move those joint chains (right now it just prints a combined list of the joint chains).
My issue is that even though the user can create multiple sets of widgets, I can only work with the last set that was created. If you try to edit the first set of selections ( in the My Tab A) or print the first set of selections(in My Tab B), it only applies to the last ones generated in the UI.
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 really believing the solution lies in creating a class for the tab creation and the selection lists.
To that end I have the below version that I think should work:
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.joint_chain_select = Create_Selection_Chains( self, self.InstanceName , "foo", "bar", "baz")
Create_Selection_Chains.set_up_Tab(self.joint_chain_select)
Create_Selection_Chains.tool_Tab(self.joint_chain_select)
def fillTabA(self, parent):
pm.setParent(parent)
cmds.text(label = 'Root Joint Selection', align ='center')
cmds.separator(h=5)
pm.button(label = 'Add Selector', c=lambda event: self.name_DialogBox())
def fillTabB(self, parent):
pm.setParent(parent)
cmds.text(label = 'FK IK Switch', align ='center')
cmds.separator(h=5)
def Remove(InstanceName):
cmds.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 USER TEXT entered as name####
self.appendJointChain()
return self.InstanceName
# if pm.window(tw, exists = True):
# pm.deleteUI(tw)
tw = TabWindow()
tw.show()
class Create_Selection_Chains():
def __init__(self, name ,InstanceName, Fks, Ikw, ikpv):
self.name=name
self.Fks = Fks
self.Ikw = Ikw
self.ikpv = ikpv
self.InstanceName= InstanceName
print Fks + Ikw + ikpv
def set_up_Tab(self):
self.setupTab = cmds.frameLayout (width = 300, label = self.InstanceName, collapse = True, collapsable = True, marginWidth = 5, parent = buildUI(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 : Create_Selection_Chains.select_joints_afk(self.joint_chain_select))
self.tsL1 = pm.textFieldButtonGrp(ed=False, adj=1,cal=(1,"left"),cw3=(10,100,25), cl3=("left","left","left") ,
buttonLabel='Wrist IK',bc= lambda : Create_Selection_Chains.select_joints_aikw(self.joint_chain_select))
self.tsL2 = pm.textFieldButtonGrp(ed=False, adj=1,cal=(1,"left"),cw3=(10,100,25), cl3=("left","left","left") ,
buttonLabel='Elbow IK',bc= lambda : Create_Selection_Chains.select_joints_ikpv(self.joint_chain_select) )
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):
self.toolTab = 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)
###################################################################################
# IK FK Switch # IK FK Switch
self.IKbutton=pm.button(label='IK', command = '', width=100)
self.FKbutton=pm.button(label='FK', command = '', width=100)
self.parent=cmds.setParent('..')
self.row2=cmds.rowLayout(numberOfColumns=2,width = 300)
###################################################################################
# IK FK Snapping # IK FK Snapping
self.Fk2IK_Button=pm.button(label='FK 2 IK', command = lambda _: Create_Selection_Chains.fk_2_ik(joint_chain_select), width=100)
self.Ik2FK_Button=pm.button(label='IK 2 FK', command = lambda _: Create_Selection_Chains.ik_2_fk(joint_chain_select), 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(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' )
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)
However, I can’t seem to get this to work. I try to add the setup tab to My UI I recieve the following errors :
self.setupTab = cmds.frameLayout (width = 300, label = self.InstanceName, collapse = True, collapsable = True, marginWidth = 5, parent = TabWindow.buildUI.tabA);
# Error: AttributeError: file <maya console> line 91: 'function' object has no attribute 'tabA' #
# Error: NameError: file <maya console> line 91: global name 'buildUI' is not defined #
when I try this:
self.setupTab = cmds.frameLayout (width = 300, label = self.InstanceName, collapse = True, collapsable = True, marginWidth = 5, parent = buildUI.tabA);
I get:
# Error: NameError: file <maya console> line 91: global name 'buildUI' is not defined #
Any assistance with this would be greatly appreciated, as Im not really sure what I’m doing wrong.