Pyqt y Maya, con Threading = False?
Pregunta
He estado investigando este problema durante 3 días, sin suerte. Soy bastante nuevo en todo esto, así que tal vez hay algo que me estoy perdiendo.
El problema se aplica a: Maya.cmds, pymel y evaluado MEL usando qthread o simplemente hilo
Este código está diseñado para funcionar en el intérprete de Python "Mayapy" que sigue a Maya. He creado un breve ejemplo que recrea el mismo error en múltiples instancias.
Un botón funciona, el otro no. Pero ejecutan el mismo código.
from PyQt4 import Qt
class doStuff( Qt.QThread ):
taskProgress = Qt.pyqtSignal(int)
# --------------------------------------------------------- #
# Here things start to crash...
def run( self ):
# This works
persp = mel.general.PyNode('persp')
print persp.translateX.get()
# This dont work
poiLights = mel.general.ls( exactType="pointLight" )
for light in poiLights:
print light
# This dont work
geo = mel.general.PyNode('pPyramidShape1')
print mel.modeling.polyEvaluate( geo, face=True )
# Emit progress
self.taskProgress.emit( 1 )
return
# END
# --------------------------------------------------------- #
class ui( Qt.QWidget ):
def __init__(self, parent=None):
super(ui, self).__init__(parent)
# Init QThread
self.thread = doStuff()
# Create Widgets
buttonNo = Qt.QPushButton("Start - Dont work")
buttonYes = Qt.QPushButton("Start - Works")
# Setup Layout
layout = Qt.QVBoxLayout()
layout.addWidget( buttonYes )
layout.addWidget( buttonNo )
self.setLayout( layout )
self.show()
# --------------------------------
# PROBLEM AREA: Button signals
# This one dont work, but starts the thread correctly.
self.connect( buttonNo, Qt.SIGNAL("clicked()"), self.thread.start )
# This one works, but dont start the thread correctly.
self.connect( buttonYes, Qt.SIGNAL("clicked()"), self.thread.run )
# --------------------------------
self.thread.taskProgress.connect( self.updateProgress )
return
# Feedback progress status
def updateProgress( self, value ):
print 'Current progress is:', value
return
if __name__ == '__main__':
import sys
app = Qt.QApplication(sys.path)
program = ui()
# init maya
import pymel.core as mel
filePath = '/Users/ecker/Dropbox/Scripts/RibExporter/mayaScene3ani.ma'
mel.openFile( filePath, f=True, o=True )
sys.exit(app.exec_())
Este código crea 2 botones que comienzan a ejecutar la misma función cuando se presiona. Uno ejecuta thread.start
y thread.run
.
thread.start
Hará que el hilo funcione como debería, poder retroalimentar los datos a la interfaz QT (para una barra de progreso), pero la mayoría del código Maya comenzará a devolver todo tipo de errores como este:
Traceback (most recent call last):
File "/Users/ecker/Dropbox/Scripts/RibExporter/error_recreation2.py", line 22, in run
poiLights = mel.general.ls( exactType="pointLight" )
File "/Applications/Autodesk/maya2012/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/pymel/core/general.py", line 969, in ls
res = _util.listForNone(cmds.ls(*args, **kwargs))
File "/Applications/Autodesk/maya2012/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/pymel/internal/pmcmds.py", line 134, in wrappedCmd
res = new_cmd(*new_args, **new_kwargs)
TypeError: Flag 'long' must be passed a boolean argument
Es un argumento booleano, y no importa qué argumentos trato de darlo en qué formato y formas, siempre dará errores muy similares a esto. En la misma línea res = new_cmd(*new_args, **new_kwargs)
Necesitando un booleano.
Necesito el thread
a start
, no solo correr. ¿A menos que haya una forma diferente de hacer el enhebrado, una solución alternativa?
Solución
Maya no funciona bien con los hilos. La clave aquí es usar maya.utils.executeinmainthreadwithresult.
Espero que esto ayude.