maya
Skapar Maya UI
Sök…
parametrar
| parameter | detaljer |
|---|---|
| e / redigera | säger Maya att du vill ändra värdet på en befintlig fastighet |
| q / fråga | säger Maya att du vill få värdet på en befintlig fastighet |
Anmärkningar
Maya kommer med en ganska komplett UI-verktygssats som innehåller fönster, layouter och en mängd olika kontroller. Detta implementeras med QT- ramverket i C ++, men exponeras för MEL- och Python-användare via standard Maya-kommandoset.
QT
Avancerade användare kan utöka Maya UI med antingen C ++ eller Python. Maya-versioner från 2012 till 2016 använder Pyside och QT4; Maya 2017 använder Pyside2 och QT5. Mer information här
Obs: Äldre referens på webben hänvisar till verktygssatsen för Maya GUI som "ELF"; det är fortfarande rätt namn men det används sällan.
Grundläggande UI-exempel [Python]
Maya GUI verktygssats skapar en mängd olika UI-element i en enkel, nödvändig form. Det finns grundläggande kommandon för att skapa och redigera GUI-widgetar; widgetarna identifieras med ett unikt strängnamn.
Alla gui-kommandon har samma grundform: du anger en kommandotyp och strängenamnet på objektet du vill arbeta med eller skapa, tillsammans med flaggor som anger utseendet eller beteendet för widgeten. Så till exempel för att skapa en knapp du använder:
cmds.button('my_button', label = 'my label')
Detta skapar en ny gui-knapp. För att redigera knappen använder du samma kommando med edit (den korta versionen är bara e ). Så du kan ändra etiketten på knappen så här:
cmds.button('my_button', e=True, label = 'a different label')
och du kan fråga det aktuella värdet på en egenskap med query eller q flaggan:
cmds.button(`my button`, q=True, label=True)
# 'a different label'
Widget-namngivning
När du skapar en ny widget med ett UI-kommando kan du ange det namn du vill att den nya widgeten ska få. Det är emellertid inte garanterat: Maya ger knappen det namn du bad om - om du har gett det ett tecken känner det inte igen eller om det redan finns en widget med samma namn kan du få tillbaka ett annat namn. Det är alltid bra att fånga namnet på en ny widget när den är skapad för att undvika överraskningar:
my_button = cmds.button('my_button')
cmds.button(my_button, e=True, label = "a new label")
Återuppringningsfunktioner
Många widgetar inkluderar händelser som kan avfyra återuppringningsfunktioner när användaren interagerar med widgeten. När du till exempel trycker på en knapp, markerar en kryssruta eller välj en nedrullning kan du avfyra en funktion.
Den exakta flaggan som är associerad med denna händelse beror på widgeten, men en typisk återuppringning ser ut så här:
def callback_fn(_ignore):
print "button pressed"
button = cmds.button(label='press me', command = callback_fn)
Genom att trycka på knappen skrivs ut "knappen tryckt" till lyssnarfönstret. De flesta widgetar avger vissa argument när deras återuppringningar aktiveras - till exempel innehåller button alltid ett booleskt värde - så du måste se till att återuppringningshanteraren har rätt signatur för att gå med widgeten du använder. Det är därför callback_fn() tar ett argument även om det inte behöver det.
Uppringning av återuppringning
Maya stöder två olika sätt att koppla återuppringningsfunktioner:
# this works, but is not a great idea
cmds.button(label = 'string reference', command = 'string_name_of_function')
# use this form whenever possible
cmds.button(label = 'direct function reference', command = callback_fn)
I det första exemplet tilldelas återuppringningen av ett strängvärde. Maya hittar återuppringningen i det globala Python-räckvidden - vilket vanligtvis är svårt att komma åt när man skriver korrekt organiserad kod. Återuppringningar av strängnamn är också långsammare att lösa. Det andra exemplet överför den faktiska Python-funktionen till återuppringningen - den här formen föredras eftersom den är snabbare och om du inte har tillhandahållit en giltig funktion till återuppringningsfunktionen vet du när UI skapas istället för när UI-widgetarna används faktiskt.
Om du vill överföra ett argumentvärde till en återuppringningsfunktion kan du använda en lambda , en nedläggning eller en funktionalitet. Partiellt binder argument till återuppringningen.
Använda partial :
from functools import partial
....
def callback_fn(myValue, _ignore): # _ignore swallows the original button argument
print myValue
button = cmds.button(label='press me', command = partial(callback_fn, "fooo"))
Använda lambda :
def callback_fn(myValue):
print myValue
button = cmds.button(label='press me', command = lambda _ignore: callback_fn("fooo"))
# here the lambda needs to handle the button argument
Använda stängningar
b = cmds.button(label = 'press me')
# by defining this function when `b` exists, we can use it later
# without storing it explicitly
def get_button_label(*_):
print "label of button", b, " is ", cmds.button(b, q=True, l=True)
cmds.button(b, e=True, c=get_button_label)
Det finns mer om sträng återuppringningsnamn kontra återuppringningsfunktion här
Skapa ett fönster
# create a window with a button that closes the window when clicked
window = cmds.window(title='example window') # create the window
layout = cmds.columnLayout(adjustableColumn=True) # add a vertical layout
def close_window(*_):
cmds.deleteUI(window) # deletes the window above
button = cmds.button(label= 'press to close", command = close_window)
# show the window
cmds.showWindow(window)
Lambdas och öglor
Lambdas är en användbar genväg för att ansluta beteenden till GUI-element.
b = cmds.button("make a cube", command = lambda _: cmds.polyCube())
På grund av hur Python fångar in variabler inuti lambdas kan du dock få oväntade resultat om du binder kommandon med lambdas i en slinga. Till exempel ser det ut som om det borde producera knappar som skapar sfärer i olika storlekar:
# warning: doesn't work like it looks!
for n in range(5):
b = cmds.button("sphere size %i" % n, command = lambda _: cmds.polySphere(radius=n))
Knapparna kommer att märkas korrekt men kommer alla att använda samma radie (4) eftersom lammdasna alla kommer att fånga det värdet när slingan stängs. TLDR: Om du genererar återuppringningar inuti en slinga, använd functools.partial eller en annan metod för att fånga värden - lambdas fungerar inte för den här applikationen. Se här för mer information