Domanda

I sviluppare strumenti di Autodesk Maya. Molti degli strumenti che costruisco sono semplici interfacce grafiche finestrate per gli animatori e modellatori da usare. Queste interfacce grafiche contengono spesso quello che normalmente si aspetta di vedere in qualsiasi finestra di base; etichette, elenchi, menu, pulsanti, campi di testo, ecc, tuttavia, non ci sono limitazioni per la complessità del interfacce utente si può costruire con gli strumenti disponibili, in particolare nei tipi di widget disponibili.

Mi interessa utilizzando alcuni dei più avanzati widget wxPython come il ListView (griglia), Albero, ecc Questo comporterebbe utilizzando una completa wxFrame (finestra) per visualizzare l'intera interfaccia utente, il che in sostanza significa che la finestra non sarebbe più legata a Maya. Non è un insuccesso, ma significa quando Maya è ridotto al minimo, la finestra non farà altrettanto.

Ho provato qualcosa di simile prima con Tkinter come un test, ma ho trovato che aveva bisogno di un MainLoop per l'esecuzione in proprio thread. Questo è logico, ma nel mio caso, è in conflitto con proprio thread di Maya, in sostanza, rendendo Maya appendere fino a quando la finestra è chiusa. Questo è dovuto al fatto che Maya esegue tutti gli script, siano essi MEL o Python, in un unico filo conduttore che le principali azioni Maya GUI. Questo per evitare che uno script, per esempio, l'eliminazione di un oggetto mentre un altro script sta cercando di fare un lavoro sullo stesso oggetto.

wxPython ha questo stesso Metodologie "mainloop". Mi chiedo se non c'è alcun modo intorno ad esso in modo che possa lavorare all'interno Maya?

È stato utile?

Soluzione

Non sono sicuro se questo è pertinente, ma un po 'googling salta fuori che PyQt è abbastanza popolare all'interno di Maya. Si potrebbe provare la tecnica qui o qui (spiegato qui con il codice sorgente) di creare un nuovo threadloop via Maya e l'esecuzione all'interno di questo. Sembra Maya ha un modulo compreso che imposta un nuovo oggetto filo, con un QApplication interno:

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = QtGui.QApplication(sys.argv)
        pumpedThread = threading.Thread(target = pumpQt, args = ())
        pumpedThread.start()

e poi imposta una funzione per elaborare gli eventi Qt:

def pumpQt():
    global app
    def processor():
        app.processEvents()
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

Probabilmente si può fare qualcosa di simile con wxPython pure. (Utils.executeDeferred è una funzione Maya.) Assicuratevi di controllare il modo di creare un non bloccante GUI sul wiki wxPython. Invece di processEvents (), ti consigliamo di impostare un ciclo di eventi e verificare la presenza di "pending" eventi all'interno della funzione (si spera rinominato?) PumpQt sopra. (La sorgente wxPython ha un pitone attuazione di MainLoop.) Probabilmente questo dovrebbe essere fatto attraverso la funzione app.Yield (), ma non sono sicuro.

def pumpWx():
    global app
    def processor():
        app.Yield(True)
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = wx.App(False)
        pumpedThread = threading.Thread(target = pumpWx, args = ())
        pumpedThread.start()

La documentazione wxPython indicano SafeYield () è preferito . Ancora una volta, questo sembra come potrebbe essere un primo passo, ma non sono sicuro che funzionerà e non solo in crash orribilmente. (C'è un po 'di discussione su ciò che si vuole fare sul wxPython mailing list ma è da un paio di versioni minori di wx fa.) C'è anche qualche indicazione in vari forum che questa tecnica causa problemi con l'input da tastiera. Si potrebbe anche provare a fare:

def processor():
  while app.Pending(): app.Dispatch()

a che fare con l'attuale elenco degli eventi.

In bocca al lupo!

Altri suggerimenti

Non so se c'è un modo per aggirare un ciclo principale per l'interfaccia grafica, in quanto è necessario per gestire tutte le catene di eventi e ridisegnare le code.

Ma ci sono diversi mezzi di comunicazione tra processi, come tubi o semafori. Forse è la possibilità di dividere il proprio interno Maya nel plug-in vero e proprio, essendo stretto in maya, e un'applicazione separata per la GUI. Questi due potrebbero utilizzare tali mezzi per comunicare e informazioni modello di scambio tra plug e gui. Non sono sicuro, però, se posso davvero consigliare questo approccio perché complica molto l'applicazione.

Si potrebbe avere uno sguardo a IPython, una shell interattiva di Python, il cui team di sviluppo ha messo qualche sforzo in integrandolo con wxPython. Hanno un modo di interrompere il ciclo degli eventi e aggancio in esso per fare le proprie cose.

Il modo migliore per andare è la creazione di un QWidget con quello che ti serve, e di utilizzarlo dall'interno di una MPxCommand attraverso l'API C ++. In questo modo si ha anche la possibilità di iniettare editor personalizzati completi in Maya via scriptedPanels.

Ma se sei destinato a Python, PyQt è la strada da percorrere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top