You might want to look into using the Pymel's new SLT ("SmartLayout") gui
builder. It is used to help put structure into the gui setup code, so that
chunks of code can be moved around easily and in turn change the actual
layout.
Also, to be consistent with the way GUI APIs are normally set up (see PyQt,
Tkinter), new GUI elements should inherit from some base GUI element (a
Window, a FormLayout, a FrameLayout, etc.)
I tried to refactor your code to this new method, and I admit the benefits
aren't too obvious in this example, but when the applications start growing
this helps keep the gui construction clean and succinct, with the ability to
change as needed.
import pymel as pm # I prefer to keep the pymel namespace, over 'from
pymel import *'
from pymel import SLT
class MyUI(pm.Window):
winName = 'myUI'
def __new__(cls):
if pm.window(cls.winName, exists=True):
pm.deleteUI(cls.winName)
self = pm.window('myUI', title="My UI")
return pm.Window.__new__(cls, self)
def __init__(self):
SLT(pm.columnLayout, 'mainLayout', childCreators=[
SLT(pm.button, 'b%s' % i, l='button_%s' % i,
c=pm.Callback(self.checkButton,i))
for i in range(5)
]).create(parent=self, creation=self.__dict__, debug=True)
self.show()
print self.mainLayout
print self.b1.getLabel()
self.b2.backgroundColor([1,0,0])
def checkButton(self, id):
btn = getattr(self, 'b%s' % i)
print btn.getLabel()
myWin = MyUI()
Below is a code snippet from a production tool that demonstrates the power
of SLT a little better:
....
def __init__(self, parent, viewOnly=False, blipNode=None, **kwargs):
SLT(childCreators=[
SLT(pm.button, "helpBtn", label="H e l p"),
SLT(pm.paneLayout, "blipnodeLayout", aft=1, st=1, ps=[1, 100,
80], configuration="horizontal2", childCreators = [
SLT(pm.verticalLayout, ratios=[0,0,1], childCreators=[
SLT(pm.horizontalLayout, ratios=[0,1], childCreators=[
SLT(pm.button, "refreshBtn", label="Refresh"),
SLT(pm.labeledControl, "blipnodeSelector",
label="blip Node:", uiFunc=pm.optionMenu, kwargs=dict(l=""), ratios=[0,1]),
]),
SLT(pm.labeledControl, "blipFilter", label="Filter:",
uiFunc=pm.textField, kwargs=dict(tx="", cc=self.refreshblipList,
ec=self.refreshblipList), ratios=[0,1]),
SLT(pm.textScrollList, "blipList",
allowMultiSelection=True, ann="blips in selected blipNode", childCreators=[
SLT(pm.popupMenu, "blipListPopup", childCreators=[
SLT(pm.menuItem,"miTL_blip",l="blip Selected",
c=lambda x : self.blipSelection(replace=True)),
SLT(pm.menuItem,"miTL_add",l="Add to Selected
blip", c=lambda x : self.blipSelection(replace=False)),
SLT(pm.menuItem,"miTL_new",l="Add to New
blip...", c=self.newAndblip),
SLT(pm.menuItem,"miTL_rename",l="Rename
blip(s)...", c=self.renameblip),
SLT(pm.menuItem, d=1),
SLT(pm.menuItem, l="Clear Selected blips",
c=lambda x : self.deleteblips()),
SLT(pm.menuItem, d=1),
SLT(pm.menuItem, l="Export Selected blips...",
c=lambda x : self.exportblips()),
SLT(pm.menuItem, l="Import blips from File
(Exact)...", c=lambda x : self.importblips(exact=True)),
SLT(pm.menuItem, l="Import blips from File
(Fuzzy)...", c=lambda x : self.importblips()),
])
])
]),
SLT(pm.verticalLayout, ratios=[0,1], spacing=0,
childCreators=[
SLT(pm.textField,"blippedData",ed=False, ann="blipped
Data"),
SLT(pm.textScrollList,"blippedList",allowMultiSelection=True, ann="blipped
Items", childCreators=[
SLT(pm.popupMenu,"blippedListPopup",postMenuCommand=self.updateblippedListPopup,
childCreators=[
SLT(pm.menuItem,"miTDL_sel",l="Select", c=lambda
x : self.selectblipped(sub=True)),
SLT(pm.menuItem,"miTDL_rem",l="Remove", c=lambda
x : self.removeItem()),
SLT(pm.menuItem, d=1),
SLT(pm.menuItem,"miTDL_info",l="<->", en=0)
])
])
])
]),
]).create(self.__dict__, parent=self)
...
- Ofer
www.mrbroken.com
On Tue, Mar 31, 2009 at 1:28 PM, John Creson <[email protected]> wrote:
> I don't know if this is already protected for by Pymel, but if you were to
> delete a bit of UI, like a shelfButton, you might want to put the deleteUI
> into an execute deferred.
> The bit below edits a shelf button that has been created "butt", to add to
> the script to be executed by the shelf button an extra bit that deletes the
> shelf button afterwards.
>
> without the execute deferred, crashing may occur.
>
> deleter = 'utils.executeDeferred(\'cmds.deleteUI("%s")\');'%(butt)
>
> script = script + deleter
>
> butt = cmds.shelfButton(butt, edit=True, command = script)
>
>
> On Tue, Mar 31, 2009 at 12:59 PM, chadrik <[email protected]> wrote:
>
>>
>> looks really good. the only thing i think i would change would be to
>> make the window name constant. as it is, it seems that under certain
>> circumstances the self.myWin attribute might not exist when the window
>> actually does.
>>
>>
>> class myUI(object):
>> winName = 'myUI'
>> def __init__(self):
>>
>> try:
>> deleteUI(self.winName)
>> except:
>> pass
>>
>> self.myWin = window(self. winName)
>> columnLayout()
>>
>> for i in range(5):
>> button('b'+str(i),l='button_'+str(i), c = Callback
>> (self.checkButton,i))
>> self.myWin.show()
>>
>> def checkButton(self,id):
>> print button('b'+str(id),query=True,label=True)
>>
>>
>> -chad
>>
>>
>>
>> On Mar 31, 2009, at 4:51 AM, marcin wrote:
>>
>> >
>> > I've question about creating dynamic ui in pymel. Is there a way to
>> > make
>> > this code more pythonic in pymel ?
>> >
>> > from pymel import *
>> >
>> > class myUI(object):
>> > def __init__(self):
>> >
>> > try:
>> > deleteUI(self.myWin)
>> > except:
>> > pass
>> >
>> > self.myWin = window()
>> > columnLayout()
>> >
>> > for i in range(5):
>> > button('b'+str(i),l='button_'+str(i), c = Callback
>> > (self.checkButton,i))
>> > self.myWin.show()
>> >
>> > def checkButton(self,id):
>> > print button('b'+str(id),query=True,label=True)
>> >
>> >
>> >
>> > >
>>
>>
>>
>>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/python_inside_maya
-~----------~----~----~----~------~----~------~--~---