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
我有一个简短的 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