Maya Python API:运行 脚本时程序未关闭

Maya Python API: Program not closing when running script

我有一个简短的 Maya 脚本,它只是将相机连续旋转一圈。问题是,当我尝试 运行 脚本时,一旦它 运行ning 我就无法关闭应用程序,直到我终止脚本。我正在使用 cmds.refresh() 但这只会刷新 UI 并且仍然会延迟其他操作(例如关闭程序)。我知道我可以手动终止脚本,但我希望能够通过回调或其他类似的东西以编程方式完成它。

这是我的代码现在的样子:

import sys
import time
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui

view = omui.M3dView.active3dView()
currentCamera = view.getCamera()

while(True):
    cmds.orbit(currentCamera, ha = 1)
    view.setCamera(currentCamera)
    cmds.refresh()
    time.sleep(.01)

基本上有什么我可以放在 while() 而不是 "True" 中的东西,它会在您关闭程序时自动终止脚本?或者我可以做一些完全不同的事情?

您可以使用附加到 idle 事件的 scriptJob 来做到这一点。

import time
import sys
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui

view = omui.M3dView.active3dView()
currentCamera = view.getCamera()

def rotate_camera():
    cmds.orbit(currentCamera, ha = 1)
    view.setCamera(currentCamera)
    cmds.refresh()
    time.sleep(.01)

cmds.scriptJob(event=['idle', rotate_camera], killWithScene=True)

这将持续旋转相机,同时允许用户随时退出应用程序或与 UI 交互。请注意,您可能需要一个回调,它会在动画结束时删除脚本作业。

你真的不想 while True: 在这里。 Maya 在线程方面相当老套——从单独的线程中触摸可见场景或 UI 是 no-no——因此如果不完全接管,就无法轻松创建所需的行为玛雅 session。不幸的是,这给了你你正在经历的行为。

您可以尝试两种基本策略:

简单的方法是使用在 'idle' 事件上触发的 Maya 脚本作业。这只会在 Maya 未执行任何其他操作时尝试 运行,并且——因为 Maya 在主线程中为您触发它——不会导致任何问题。然而,这只会在 Maya 没有做任何其他事情时触发——因此,如果用户正在 UI 或场景中做某事,您的脚本将不会触发。类似于:

def orbit_cam():
   cmds.orbit('persp', ha = .01)

cmds.scriptJob(e=('idle', orbit_cam))

这样做的最大缺点是您无法控制脚本触发的频率:这取决于 Maya。

第二个选项是创建一个单独的线程来根据您自己的条件触发脚本。但是你必须在这里小心,因为从第二个线程激发的函数会导致崩溃,除非你将它们包装在对 maya.util.executeDeferred 的调用中。

更多背景:How to use python (maya) multithreading and How to execute a Maya MEL procedure at regular intervals