Pregunta

I desarrollar herramientas de Autodesk Maya. Muchas de las herramientas que construyo tienen interfaces gráficas de usuario con ventanas sencillas para los animadores y modeladores para su uso. Estas interfaces gráficas de usuario contienen a menudo de lo que normalmente esperaría ver en cualquier ventana básica; etiquetas, listas, menús, botones, campos de texto, etc. Sin embargo, existen limitaciones a la complejidad de la IU se puede construir con las herramientas disponibles, específicamente en los tipos de widgets disponibles.

Estoy interesado en el uso de algunos de los widgets más avanzados wxPython como el ListView (rejilla), Árbol, etc. Esto implicaría el uso de un wxFrame completa (ventana) para mostrar toda la interfaz de usuario, lo que significaría en esencia esa ventana ya no estar atado a Maya. No es un tema de oferta, sino que significa cuando se minimiza Maya, la ventana no será lo mismo.

He intentado algo como esto antes con tkinter como una prueba, pero encontré que necesitaba un MainLoop para funcionar en su propio hilo. Esto es lógico, pero en mi caso, entra en conflicto con el propio hilo de Maya, esencialmente haciendo Maya cuelgue hasta que la ventana está cerrada. Esto es debido al hecho de que Maya se ejecuta todos los scripts, ya sean MEL o Python, en un solo hilo que las principales acciones Maya GUI. Esto es para evitar un script de, por ejemplo, la eliminación de un objeto, mientras que otro guión está tratando de hacer el trabajo en el mismo objeto.

wxPython tiene esta misma metodologia "mainloop". Me pregunto si hay alguna manera de evitarlo para que pueda trabajar dentro de Maya?

¿Fue útil?

Solución

No estoy seguro de si esto es pertinente, pero algunas google gira hasta que PyQt es muy popular dentro de Maya. Usted podría intentar la técnica aquí o aquí (explicado aquí con el código fuente) de crear un nuevo threadloop a través de Maya y ejecución dentro de ello. Parece Maya tiene un módulo incluido que pone en marcha un nuevo objeto hilo, con un QApplication dentro de él:

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

y después establece una función para procesar los eventos Qt:

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

Puede probablemente hacer algo similar con wxPython también. (Utils.executeDeferred es una función Maya). Asegúrese de revisar cómo crear un no bloqueante GUI en el wiki de wxPython. En lugar de processEvents (), tendrá que establecer un bucle de eventos y comprobar si hay eventos "en espera" dentro de la función (es de esperar cambiado el nombre?) PumpQt anteriormente. (La fuente wxPython tiene una Python aplicación de MainLoop.) Probablemente esto se debe hacer a través de la función app.Yield (), pero no estoy seguro.

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

Los docs wxPython indican SafeYield () se prefiere . Una vez más, esto parece que podría ser un primer paso, pero no estoy seguro de que funcionará y no sólo fallará estrepitosamente. (Hay una cierta discusión acerca de lo que quiere hacer en el wxPython lista de correo pero es de unas pocas versiones menores de wx hace.) también hay algunos indicios en diversos foros que esta técnica provoca problemas con la entrada de teclado. También puede intentar hacer:

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

para hacer frente a la lista actual de los acontecimientos.

Buena suerte!

Otros consejos

No sé si hay una manera alrededor de un lazo principal de la interfaz gráfica de usuario, ya que se necesita para manejar todas las cadenas de eventos y volver a dibujar las colas.

Pero hay varios medios de comunicación entre procesos, como tuberías o semáforos. Tal vez se trata de una opción de dividir su extensión Maya en el plugin real, siendo apretada en maya, y una solicitud por separado para la interfaz gráfica de usuario. Estos dos podrían usar tales medios para comunicar y la información del modelo de cambio entre plugin y GUI. No estoy seguro, sin embargo, si realmente puedo recomendar este enfoque, ya que complica mucho la aplicación.

Se puede echar un vistazo a IPython, un terminal de Python interactiva, cuyo equipo de desarrollo ha realizado algunos esfuerzos para integrarla con wxPython. Tienen alguna forma de interrumpir el ciclo de eventos y enganchando en él para hacer sus propias cosas.

La mejor forma de hacerlo es crear un QWidget con lo que necesita, y su uso dentro de un MPxCommand a través de la API C ++. De esta forma usted también tiene la oportunidad de inyectar editores personalizados completos en Maya a través de scriptedPanels.

Pero si usted está obligado a Python, PyQt es el camino a seguir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top