0

加载或保存 nuke 脚本后,我需要在 Nuke(合成软件)中刷新(更新)GUI 小部件(pySide)。回调:nuke.addOnScriptSave() 和 nuke.addOnScriptLoad()

import nuke
from PySide import QtGui, QtCore
from nukescripts import panels


class Info(QtGui.QWidget):
    def __init__(self,  parent=None):
        QtGui.QWidget.__init__(self, parent)      
        self.initUI()

    def scriptName(self): 
        sName = (nuke.root().name()).split('/')#split name from root
        return sName


    def initUI(self): 

        self.lbl1 = QtGui.QLabel("script name : " , self)

        layout = QtGui.QHBoxLayout()#main layout
        layout.addWidget(self.lbl1) 
        self.setLayout(layout)

        self.updateInfo()

    def updateInfo(self):

        scriptName = self.scriptName()

        self.lbl1.setText("script name : " + scriptName[-1].split('.')[0])#set name 


panels.registerWidgetAsPanel('Info', 'Info_script', 'infoscript')
4

1 回答 1

0

简单的解决方案是将回调注册添加到小部件的__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方法中,当小部件被操作系统级别的窗口操作以外的东西隐藏时,回调将被取消注册。这是非常可靠的,除了当您更改到小部件窗格中的另一个选项卡(如果它已停靠)时,您的回调也将被取消注册。但是,当您的选项卡再次激活时,它们显然会被重新添加。这是一个很小的惩罚,但我仍然认为值得指出的是,虽然这种方法非常接近理想,但它并不完美。

无论如何,我会让你决定你更喜欢这两个中的哪一个,但我希望这会有所帮助。

于 2014-12-05T06:49:58.290 回答