Frage

Ich entwickle Werkzeuge in Autodesk Maya. Viele der Werkzeuge, die ich bauen einfache Fenster-GUIs für die Animatoren und Modellierer zu verwenden. Diese GUIs enthalten oft, was man normalerweise in einem Grundfenster erwarten; Etiketten, Listen, Menüs, Schaltflächen, Textfelder usw. Allerdings gibt es Einschränkungen bezüglich der Komplexität des UIs Sie mit den verfügbaren Werkzeugen, insbesondere in der Art der verfügbaren Widgets bauen können.

Ich habe Interesse an einigen der fortgeschritteneren WxPython Widgets wie das Listview (Gitter) mit, Baum, usw. ein komplettes wxFrame (Fenster) mit sich bringen würde die gesamte Benutzeroberfläche angezeigt werden, die im Wesentlichen das Fenster bedeuten würde würde nicht mehr zu Maya gebunden werden. Nicht ein Deal Breaker, aber es bedeutet, wenn Maya minimiert wird, wird das Fenster nicht nachziehen.

Ich habe so etwas wie dies vorher versucht mit tkinter als Test, fand aber, dass es eine MainLoop benötigt in einem eigenen Thread ausgeführt werden. Dies ist logisch, aber in meinem Fall, es in Konflikt mit Maya eigenem Thread im Wesentlichen macht Maya hängen, bis das Fenster geschlossen ist. Dies ist aufgrund der Tatsache, dass Maya alle Skripte ausgeführt wird, werden sie MEL oder Python, in einem einzigen Thread, dass die Hauptanteile Maya GUI. Dies ist ein Skript, um zu verhindern, sagen wir, ein Objekt zu löschen, während ein anderes Skript versucht, die Arbeit an demselben Objekt zu tun.

wxPython hat die gleiche "mainloop" Methodik. Ich frage mich, wenn es um es irgendeine Art und Weise ist, so dass es in Maya arbeiten?

War es hilfreich?

Lösung

Ich bin mir nicht sicher, ob dies relevant ist, aber einige googeln auftauchen, dass PyQt innerhalb von Maya ziemlich populär ist. Sie könnten die Technik versuchen hier oder hier (erklärt hier mit Source-Code) einen neuen threadloop über Maya zu schaffen und im Innern davon ausgeführt wird. Es scheint, Maya ein Modul hat enthalten, die ein neues Thread-Objekt, mit einem QApplication darin einrichtet:

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

und dann eine Funktion einrichtet, die Qt-Ereignisse zu verarbeiten:

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

Sie können wahrscheinlich auch etwas ähnliches mit wxPython tun. (Utils.executeDeferred ist eine Maya-Funktion.) Achten Sie darauf, um zu überprüfen, wie ein non-blocking GUI auf dem wxPython Wiki. Statt process (), sollten Sie eine Ereignisschleife einzurichten und überprüfen für „Pending“ Ereignisse in der (hoffentlich umbenannt?) PumpQt Funktion oben. (Die WxPython Quelle hat eine Python-Implementierung wahrscheinlich von MainLoop.) sollte dies durch den app.Yield () Funktion durchgeführt werden, aber ich bin mir nicht sicher.

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()

Die WxPython docs zeigen SafeYield () bevorzugt wird . Auch hier scheint dies wie es ein erster Schritt sein könnte, aber ich bin nicht sicher, wird es funktionieren und nicht nur schrecklich abstürzen. (Es gibt einige Diskussionen über das, was Sie auf der WxPython Liste Mailing, aber es ist von einigen kleineren Versionen von wx vor.) es gibt auch Hinweise darauf, in verschiedenen Foren, die diese Technik Probleme mit Tastatureingabe verursacht. Sie könnten auch versuchen zu tun:

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

mit der aktuellen Liste von Ereignissen befassen.

Viel Glück!

Andere Tipps

Ich weiß nicht, ob es eine Möglichkeit, um eine mainloop für die gui ist, da es alle Ereignisketten zu handhaben benötigt wird, und neu zu zeichnen Warteschlangen.

Aber es gibt mehrere Mittel zur Interprozesskommunikation, wie Rohre oder Semaphoren. Vielleicht ist es eine Option, um Ihre Maya-Erweiterung in das eigentliche Plugin zu spalten, wobei fest in maya, und eine separate Anwendung für die GUI. Diese beiden könnten solche Mittel verwenden, um die Kommunikation und den Austausch von Modellinformationen zwischen Plugin und gui. Ich bin nicht sicher, aber wenn ich wirklich diesen Ansatz empfehlen kann, weil es sehr viel um die Anwendung erschwert.

Sie können einen Blick auf IPython haben, eine interaktive Python-Shell, Team, dessen Entwickler einige Mühe in die Integration mit wxPython gesetzt hat. Sie haben in gewisser Weise die Ereignisschleife zu unterbrechen und Einhaken in sie ihre eigenen Sachen zu tun.

Der beste Weg, um eine QWidget mit zu gehen ist zu schaffen, was Sie brauchen, und es innerhalb eines MPxCommand durch die C ++ API. So können Sie auch die Möglichkeit haben, kompletten kundenspezifische Editoren in Maya über scriptedPanels zu injizieren.

Wenn Sie aber Python gebunden sind, dann ist pyqt der Weg zu gehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top