使用 class 中的当前值对 运行 函数使用回调
Using callbacks to run function using the current values in a class
一时想不出一个好的标题,就在这里解释一下吧。我在 Maya 中使用 Python,它有一些事件回调选项,因此您可以执行类似 on save: run function
的操作。我有一个用户界面 class,我希望它在某些事件被触发时更新,我可以做到,但我正在寻找一种更简洁的方法。
这是一个类似于我的基本示例:
class test(object):
def __init__(self, x=0):
self.x = x
def run_this(self):
print self.x
def display(self):
print 'load user interface'
#Here's the main stuff that used to be just 'test().display()'
try:
callbacks = [callback1, callback2, ...]
except NameError:
pass
else:
for i in callbacks:
try:
OpenMaya.MEventMessage.removeCallback(i)
except RuntimeError:
pass
ui = test(5)
callback1 = OpenMaya.MEventMessage.addEventCallback('SomeEvent', ui.run_this)
callback2 = OpenMaya.MEventMessage.addEventCallback('SomeOtherEvent', ui.run_this)
callback3 = ......
ui.display()
回调会一直持续到 Maya 重新启动,但如果您向它传递从 addEventCallback
返回的值,则可以使用 removeCallback
将其删除。我现在的方法就是在设置变量之前检查是否设置了变量,这比test().display()
的前一行要混乱很多
有什么方法可以在函数中巧妙地做到这一点吗?如果我再次 运行 test
class 或类似的东西,它会删除旧的东西吗?
您可以通过两种方式进行尝试。
您可以拥有一个表示回调管理器的持久对象,并允许它自己挂钩和脱钩。
import maya.api.OpenMaya as om
import maya.cmds as cmds
om.MEventMessage.getEventNames()
class CallbackHandler(object):
def __init__(self, cb, fn):
self.callback = cb
self.function = fn
self.id = None
def install(self):
if self.id:
print "callback is currently installed"
return False
self.id = om.MEventMessage.addEventCallback(self.callback, self.function)
return True
def uninstall(self):
if self.id:
om.MEventMessage.removeCallback(self.id)
self.id = None
return True
else:
print "callback not currently installed"
return False
def __del__(self):
self.uninstall()
def test_fn(arg):
print "callback fired 2", arg
cb = CallbackHandler('NameChanged', test_fn)
cb.install()
# callback is active
cb.uninstall()
# callback not active
cb.install()
# callback on again
del(cb) # or cb = None
# callback gone again
在此版本中,只要您希望回调持续存在,您就会存储您创建的 CallbackHandlers,然后在您不再需要它们时手动卸载它们或让它们脱离范围。
另一种选择是创建您自己的对象来表示回调,然后添加或删除您希望它在您自己的代码中触发的任何函数。这使管理完全站在你这边,而不是依赖 api,这可能是好是坏取决于你的需要。您将有一个可调用的 Event()
class(使用 __call__()
并且它会有一个要触发的函数列表,然后它的 __call__()
被 Maya 调用。有一个您想要的事件处理程序对象类型的示例 here
一时想不出一个好的标题,就在这里解释一下吧。我在 Maya 中使用 Python,它有一些事件回调选项,因此您可以执行类似 on save: run function
的操作。我有一个用户界面 class,我希望它在某些事件被触发时更新,我可以做到,但我正在寻找一种更简洁的方法。
这是一个类似于我的基本示例:
class test(object):
def __init__(self, x=0):
self.x = x
def run_this(self):
print self.x
def display(self):
print 'load user interface'
#Here's the main stuff that used to be just 'test().display()'
try:
callbacks = [callback1, callback2, ...]
except NameError:
pass
else:
for i in callbacks:
try:
OpenMaya.MEventMessage.removeCallback(i)
except RuntimeError:
pass
ui = test(5)
callback1 = OpenMaya.MEventMessage.addEventCallback('SomeEvent', ui.run_this)
callback2 = OpenMaya.MEventMessage.addEventCallback('SomeOtherEvent', ui.run_this)
callback3 = ......
ui.display()
回调会一直持续到 Maya 重新启动,但如果您向它传递从 addEventCallback
返回的值,则可以使用 removeCallback
将其删除。我现在的方法就是在设置变量之前检查是否设置了变量,这比test().display()
有什么方法可以在函数中巧妙地做到这一点吗?如果我再次 运行 test
class 或类似的东西,它会删除旧的东西吗?
您可以通过两种方式进行尝试。
您可以拥有一个表示回调管理器的持久对象,并允许它自己挂钩和脱钩。
import maya.api.OpenMaya as om
import maya.cmds as cmds
om.MEventMessage.getEventNames()
class CallbackHandler(object):
def __init__(self, cb, fn):
self.callback = cb
self.function = fn
self.id = None
def install(self):
if self.id:
print "callback is currently installed"
return False
self.id = om.MEventMessage.addEventCallback(self.callback, self.function)
return True
def uninstall(self):
if self.id:
om.MEventMessage.removeCallback(self.id)
self.id = None
return True
else:
print "callback not currently installed"
return False
def __del__(self):
self.uninstall()
def test_fn(arg):
print "callback fired 2", arg
cb = CallbackHandler('NameChanged', test_fn)
cb.install()
# callback is active
cb.uninstall()
# callback not active
cb.install()
# callback on again
del(cb) # or cb = None
# callback gone again
在此版本中,只要您希望回调持续存在,您就会存储您创建的 CallbackHandlers,然后在您不再需要它们时手动卸载它们或让它们脱离范围。
另一种选择是创建您自己的对象来表示回调,然后添加或删除您希望它在您自己的代码中触发的任何函数。这使管理完全站在你这边,而不是依赖 api,这可能是好是坏取决于你的需要。您将有一个可调用的 Event()
class(使用 __call__()
并且它会有一个要触发的函数列表,然后它的 __call__()
被 Maya 调用。有一个您想要的事件处理程序对象类型的示例 here