PyQt 和 Maya,线程 = False?

发布于 2025-01-06 09:40:48 字数 3524 浏览 0 评论 0原文

我已经研究这个问题三天了,没有任何运气。我对这一切都很陌生,所以也许我遗漏了一些东西。

该问题适用于:Maya.cmds、PyMel 和使用 QThread 或仅使用 Thread 评估的 MEL

此代码设计为在 Maya 后面的“mayapy”python 解释器上运行。我创建了一个简短的示例,它在多个实例中重新创建相同的错误。

一个按钮有效,另一个按钮无效。但它们运行相同的代码。

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

此代码创建 2 个按钮,按下这些按钮后开始执行相同的功能。其中一个执行 thread.startthread.run

thread.start 将使线程按其应有的方式工作,能够将数据反馈到 Qt 界面(用于进度条),但大多数 Maya 代码将开始返回各种错误像这样:

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

它是一个布尔参数,无论我尝试以什么格式和方式给出什么参数,它总是会给出与此非常相似的错误。在同一行 res = new_cmd(*new_args, **new_kwargs) 需要一个布尔值。

我需要线程启动,而不仅仅是运行。除非有不同的方法来进行线程处理,有解决方法吗?

I've been investigating this problem for 3 days now, without any luck. I'm quite new to all this so maybe there is something I'm missing.

The problem applies to: Maya.cmds, PyMel and evaluated MEL using QThread or just Thread

This code is designed to run on the "mayapy" python interpreter which follows Maya. I've created a short example which re-creates the same error in multiple instances.

One button works, the other one doesn't. But they run the same code.

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

This code creates 2 buttons which start executing the same function when pressed. One executes thread.start and thread.run.

thread.start will make the thread work as it should, being able to feed back data to the Qt interface (for a progress bar), but most of the Maya code will start to return all kinds of errors like this:

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

It is a boolean argument, and no matter what arguments I try to give it in what format and ways, it will always give errors very similar to this. At the same line res = new_cmd(*new_args, **new_kwargs) needing a boolean.

I need the thread to start, not just run. Unless there is a different way to do the threading, a workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晌融 2025-01-13 09:40:48

Maya 不能很好地处理线程。这里的关键是使用maya.utils.executeInMainThreadWithResult。

http://download.autodesk.com/us/maya/2010help/index.html?url=Python_Python_and_threading.htm,topicNumber=d0e182779

我希望这会有所帮助。

Maya does not work well with threads. The key here is to use maya.utils.executeInMainThreadWithResult.

http://download.autodesk.com/us/maya/2010help/index.html?url=Python_Python_and_threading.htm,topicNumber=d0e182779

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文