【问题标题】:Maya GUI freezes during subprocess callMaya GUI 在子进程调用期间冻结
【发布时间】:2016-03-21 18:23:43
【问题描述】:

我需要对我们从客户那里收到的一些 Maya 场景进行整合,以使它们与我们的流程兼容。显然,我想批量处理该操作,并要求我从 Maya 中启动该过程。
我已经尝试了两种方法(彼此非常相似),这两种方法都有效,但问题是 Maya GUI 会冻结,直到该过程完成。我希望这个过程对用户来说是完全透明的,这样他们就可以保持工作状态,并且在完成后只有一条消息。
以下是我迄今为止尝试和发现的内容:
这个教程在这里:http://www.toadstorm.com/blog/?p=136 引导我写这个并保存它:

filename = sys.argv[1]

def createSphere(filename):
    std.initialize(name='python')
    try:
        mc.file(filename, open=True, pmt=False, force=True)
        sphere = mc.polySphere() [0]
        mc.file(save=True, force=True)
        sys.stdout.write(sphere)
    except Exception, e:
        sys.stderr.write(str(e))
        sys.exit(-1)
    if float(mc.about(v=True)) >= 2016.0:
        std.uninitialize()

createSphere(filename)

然后以这种方式从 Maya 中调用它:

mayapyPath = 'C:/Program Files/Autodesk/Maya2016/bin/mayapy.exe'
scriptPath = 'P:/WG_MAYA_Users/lbouet/scripts/createSphere.py'
filenames = ['file1', 'file2', 'file3', 'file4']

def massCreateSphere(filenames):
    for filename in filenames:
        maya = subprocess.Popen(mayapyPath+' '+scriptPath+' '+filename,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        out,err = maya.communicate()
        exitcode = maya.returncode
        if str(exitcode) != '0':
            print(err)
            print 'error opening file: %s' % (filename)
        else:
            print 'added sphere %s to %s' % (out,filename)

massCreateSphere(filenames)

它工作正常,但就像我说的,冻结 Maya GUI 直到过程结束。而且它只是为了创建一个球体,所以几乎没有接近我在场景中实际必须执行的所有动作。
我还尝试通过调用 mayabatch 的 .bat 文件运行第一个脚本并运行脚本,同样的问题。
我发现这个帖子 (Running list of cmd.exe commands from maya in Python) 似乎正是我想要的,但我看不出如何适应我的情况?
据我了解,这个问题可能来自循环调用 Popen (即多次),但我真的不知道该怎么做......我在想也许将第二个脚本也保存在磁盘上的某个地方并调用它一个来自玛雅?

【问题讨论】:

    标签: python python-2.7 maya


    【解决方案1】:

    在这种情况下,subprocess.communicate() 将阻塞直到子进程完成,因此它不会自行解决您的问题。

    如果您只想启动进程而不是等待它们完成——“即发即弃”风格——你可以只使用线程,为每个进程启动一个新线程。但是,您必须非常小心地向用户报告——如果您尝试从外部线程触摸 Maya 场景或 GUI,您将得到神秘的、无法调试的错误。 print()通常可以,但maya.cmds() 不行。如果您只打印消息,您可能会使用 maya.utils.executeDeferred() 来解决问题,这是在 in this question 和 in the docs 中讨论的。

    【讨论】:

    • 是的,这就是我意识到的。当我启动它来处理各种文件时,没有subprocess.communicate() 它会根据需要打开尽可能多的控制台,完成工作,在控制台上打印输出并在打开时尽快关闭。说maya.cmds 不行,您的意思是您不建议使用该方法对maya 场景进行一些更改?谢谢你的链接,我马上去阅读。
    • 基本上,您不应该尝试从主线程以外的线程从maya.cmds 发出任何内容,除非它被包裹在maya.utils.executeDeferred 中。这有点过于简单化了,但它是一个很好的经验法则。您仍然可以在 other maya 实例中以通常的方式使用cmds - 但是在用户看到的实例中,不要触摸线程中的 cmds
    • 感谢您的回复。我不得不承认英语不是我的主要语言加上我自己学习 python 使得一些概念仍然很难掌握,但我会继续挖掘。我认为现在我将继续使用主线程中的子进程,因为我确实需要一些输出。
    猜你喜欢
    • 1970-01-01
    • 2014-08-15
    • 2018-04-15
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多