简单的解决方案是将回调注册添加到小部件的__init__
:
class Info(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.initUI()
nuke.addOnScriptSave(self.updateInfo)
if nuke.root().name() == 'Root' and not nuke.modified():
# No reason to add a scriptLoad callback if opening a
# script would spawn a new Nuke process.
nuke.addOnScriptLoad(self.updateInfo)
# Rest of the class definition omitted for brevity
这种方法确实有一个明显的缺点:因为 Nuke 的回调注册表现在将包含至少一个对小部件updateInfo
方法的引用,所以 Python 永远不会对小部件进行垃圾收集。这在现实生活中可能永远不会有太大的影响,因为您可能只会创建非常少量的面板实例,但是如果您曾经创建过 1000 个实例,那么您将注册 1000 个回调,这些回调永远不会未注册(即使面板已关闭)。
不幸的是,当你的小部件从 UI 中删除时,Nuke 并没有真正给你任何钩子来实现,所以很难有一个可靠的方法来知道是时候取消注册你的回调了。您可以获得的最接近的可能是使用showEvent
/hideEvent
组合和一些猜测,如下所示:
class Info(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.initUI()
self.callbacksRegistered = False
def addCallbacks(self):
nuke.addOnScriptSave(self.updateInfo)
if nuke.root().name() == 'Root' and not nuke.modified():
# No reason to add a scriptLoad callback if opening a
# script would spawn a new Nuke process.
nuke.addOnScriptLoad(self.updateInfo)
def removeCallbacks(self):
self.removeOnScriptSave(self.updateInfo)
self.removeOnScriptLoad(self.updateInfo)
def showEvent(self, event):
if not (self.callbacksRegistered or event.spontaneous()):
self.addCallbacks()
self.callbacksRegistered = True
def hideEvent(self, event):
if self.callbacksRegistered and not event.spontaneous():
# "Spontaneous" hide events are sent when the Nuke
# window is minimized, which we don't really care
# about.
self.removeCallbacks()
self.callbacksRegistered = False
# Rest of the class definition omitted for brevity
回调注册被移到showEvent
方法中,当小部件被操作系统级别的窗口操作以外的东西隐藏时,回调将被取消注册。这是非常可靠的,除了当您更改到小部件窗格中的另一个选项卡(如果它已停靠)时,您的回调也将被取消注册。但是,当您的选项卡再次激活时,它们显然会被重新添加。这是一个很小的惩罚,但我仍然认为值得指出的是,虽然这种方法非常接近理想,但它并不完美。
无论如何,我会让你决定你更喜欢这两个中的哪一个,但我希望这会有所帮助。