PyQt und Maya, mit Threading = False?
Frage
Ich untersuche dieses Problem jetzt seit drei Tagen, ohne Erfolg.Ich bin in diesem Bereich ziemlich neu, also übersehe ich vielleicht etwas.
Das Problem betrifft: Maya.cmds, PyMel und evaluierte MEL mit QThread oder einfach Thread
Dieser Code ist für die Ausführung auf dem Python-Interpreter „mayapy“ konzipiert, der Maya folgt.Ich habe ein kurzes Beispiel erstellt, das denselben Fehler in mehreren Instanzen erneut erzeugt.
Eine Taste funktioniert, die andere nicht.Aber sie führen den gleichen Code aus.
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_())
Dieser Code erstellt zwei Tasten, die beim Drücken dieselbe Funktion ausführen.Einer führt aus thread.start
Und thread.run
.
thread.start
sorgt dafür, dass der Thread so funktioniert, wie er sollte, und kann Daten an die Qt-Schnittstelle zurückmelden (für einen Fortschrittsbalken), aber der größte Teil des Maya-Codes wird anfangen, alle möglichen Fehler wie diesen zurückzugeben:
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 ist ein boolesches Argument, und egal, welche Argumente ich versuche, in welchem Format und auf welche Art und Weise es anzugeben, es wird immer Fehler geben, die diesem sehr ähnlich sind.Auf der gleichen Linie res = new_cmd(*new_args, **new_kwargs)
Ich brauche einen booleschen Wert.
Ich brauche das thread
Zu start
, nicht nur laufen.Gibt es eine Problemumgehung, es sei denn, es gibt eine andere Möglichkeit, das Threading durchzuführen?
Lösung
Maya funktioniert nicht gut mit Threads.Der Schlüssel hier ist die Verwendung von maya.utils.executeInMainThreadWithResult.
Ich hoffe das hilft.