maya
Creazione dell'interfaccia utente di Maya
Ricerca…
Parametri
| parametro | dettagli |
|---|---|
| e / edit | dice a Maya che vuoi cambiare il valore di una proprietà esistente |
| q / query | dice a Maya che vuoi ottenere il valore di una proprietà esistente |
Osservazioni
Maya viene fornito con un kit di strumenti dell'interfaccia utente abbastanza completo che include finestre, layout e una varietà di controlli. Questo è implementato usando il framework QT in C ++, ma è esposto agli utenti MEL e Python tramite il set di comandi Maya predefinito.
QT
Gli utenti esperti possono estendere l'interfaccia utente di Maya usando C ++ o Python. Le versioni Maya dal 2012 al 2016 utilizzano Pyside e QT4; Maya 2017 utilizza Pyside2 e QT5. Maggiori dettagli qui
Nota: i riferimenti precedenti sul Web si riferiscono al toolkit della GUI Maya come "ELF"; è ancora il nome corretto ma è usato raramente.
Esempio di interfaccia utente di base [Python]
Il toolkit Maya GUI crea una varietà di elementi dell'interfaccia utente in una forma semplice e imperativa. Esistono comandi di base per creare e modificare i widget della GUI; i widget sono identificati da un nome di stringa univoco.
Tutti i comandi di GUI hanno la stessa forma di base: si fornisce un tipo di comando e il nome della stringa dell'oggetto su cui si vuole lavorare o creare, insieme a flag che specificano l'aspetto o il comportamento del widget. Quindi, ad esempio, per creare un pulsante devi usare:
cmds.button('my_button', label = 'my label')
Questo creerà un nuovo pulsante GUI. Per modificare il pulsante si usa lo stesso comando con il flag di edit (la versione breve è solo e ). Quindi potresti cambiare l'etichetta del pulsante in questo modo:
cmds.button('my_button', e=True, label = 'a different label')
e puoi interrogare il valore corrente di una proprietà con la query o il flag q :
cmds.button(`my button`, q=True, label=True)
# 'a different label'
Denominazione dei widget
Quando crei un nuovo widget con un comando dell'interfaccia utente, puoi fornire il nome che vorresti ottenere dal nuovo widget. Tuttavia, non è garantito: Maya assegnerà al pulsante il nome che hai richiesto - se gli hai assegnato un carattere che non riconosce o se esiste già un widget con lo stesso nome, puoi ottenere un nome diverso. È sempre buona norma acquisire il nome di un nuovo widget quando viene creato per evitare sorprese:
my_button = cmds.button('my_button')
cmds.button(my_button, e=True, label = "a new label")
Funzioni di callback
Molti widget includono eventi che possono attivare le funzioni di callback quando l'utente interagisce con il widget. Ad esempio quando si preme un pulsante, si seleziona una casella di controllo o si seleziona un menu a discesa è possibile attivare una funzione.
Il flag esatto associato a questi eventi dipende dal widget, ma un tipico callback sarà simile a questo:
def callback_fn(_ignore):
print "button pressed"
button = cmds.button(label='press me', command = callback_fn)
Premendo il pulsante verrà stampato il "pulsante premuto" sulla finestra dell'ascoltatore. La maggior parte dei widget attivano alcuni argomenti quando i loro callback si attivano - il button ad esempio include sempre un valore booleano - quindi è necessario assicurarsi che il gestore di callback abbia la firma giusta per andare con il widget che si sta utilizzando. Ecco perché callback_fn() accetta un argomento anche se non ne ha bisogno.
Assegnazione callback
Maya supporta due diversi modi di collegare le funzioni di callback:
# 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)
Nel primo esempio il callback è assegnato da un valore stringa. Maya troverà il callback nell'oscillazione globale Python, che di solito è difficile accedere quando si scrive codice correttamente organizzato. Anche i callback con stringhe sono più lenti da risolvere. Il secondo esempio passa la funzione Python effettiva al callback - questo modulo è preferito perché è più veloce e, se non hai fornito una funzione valida alla funzione di callback, saprai quando viene creata l'interfaccia utente anziché quando i widget dell'interfaccia utente vengono effettivamente utilizzati.
Se si desidera passare un valore argomento a una funzione di richiamata, è possibile utilizzare un argomento lambda , una chiusura o functools.partial per il richiamo.
Utilizzo 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"))
Utilizzando 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
Utilizzando le chiusure
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)
Ci sono ulteriori informazioni sui nomi delle callback delle stringhe e sulla funzione di callback qui
Creare una finestra
# 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)
Lambda e anelli
Lambdas è una scorciatoia utile per collegare i comportamenti agli elementi della GUI.
b = cmds.button("make a cube", command = lambda _: cmds.polyCube())
Tuttavia, a causa del modo in cui Python cattura le variabili all'interno di lambda, è possibile ottenere risultati imprevisti se si associano i comandi usando lambdas all'interno di un ciclo. Ad esempio, sembra che dovrebbe produrre pulsanti che creano sfere di dimensioni diverse:
# 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))
I pulsanti saranno etichettati correttamente ma useranno tutti lo stesso raggio (4) perché tutti i lambda cattureranno quel valore quando il ciclo si chiude. TLDR: se stai creando callback all'interno di un ciclo, usa functools.partial o un altro metodo per acquisire valori - lambda non funziona per questa applicazione. Vedi qui per maggiori dettagli