• 能否在Python中利用 MPxNode 的构造和析构函数来添加和删除事件?


    最近有看到一个case,用户用Python自定义了一个节点,然后在自定义节点的构造函数 __init__ 中注册了一个事件回调函数,并且在相应的析构函数__del__ 中把对应的事件删除掉。代码看起来似乎没有什么问题,但是当用户执行的时候,发现该事件总是无法被删除掉。无论是重新建一个场景,或者是删除这个节点,甚至是卸载这个插件,该事件一直存在,没有被删除掉。 

    import sys

    import maya.OpenMaya as OpenMaya

    import maya.OpenMayaMPx as OpenMayaMPx

    nodeName = "TestNode"

    nodeId = OpenMaya.MTypeId(0x102fff)

    class Test(OpenMayaMPx.MPxNode):

        idCallback = None

            

        def __init__(self):

            OpenMayaMPx.MPxNode.__init__(self)   

            if self.idCallback==None :

                self.idCallback = OpenMaya.MEventMessage.addEventCallback("SelectionChanged",self.callbackFunc)       

        def __del__(self):

            try:

                OpenMaya.MEventMessage.removeCallback(self.idCallback)

            except:

                print str(self.idCallback) + "already destroyed."

       

        def callbackFunc(self,*args):

            print "Called"

        def compute(self, plug, dataBlock):

            print "compute"

    def nodeCreator():

        nodePtr = OpenMayaMPx.asMPxPtr(Test())

        return nodePtr

    def nodeInitializer():

        print "nodeInitializer"

       

    def initializePlugin(mobject):

        mplugin = OpenMayaMPx.MFnPlugin(mobject)

        try:

            mplugin.registerNode(nodeName, nodeId, nodeCreator, nodeInitializer)       

        except:

            sys.stderr.write("Failed to register node: %s" % nodeName)

            raise

    def uninitializePlugin(mobject):

        mplugin = OpenMayaMPx.MFnPlugin(mobject)

        try:

            mplugin.deregisterNode(nodeId)

        except:

            sys.stderr.write("Failed to deregister node: %s" % nodeName)

            raise

    仔细看了下问题并且在Maya环境中运行了下,发现问题在于析构函数__del__中,该函数在上述几种情况下一直无法被调用到。查了下Python析构函数的特性,这才发现了问题原因所在。 

    因为Python是用了自动垃圾回收(GC)来管理其内存的,也就是说,对象的真正析构时机是由GC来控制的。那么,当我们新建场景,删除节点,或者是卸载插件的时候,虽然表面上看该节点已经被删除了,但是其实际上很有可能还没有被GC回收,所以该析构函数也就一直没有被调用到。 

    如果想要让对象被删除掉,可以直接显式调用删除语句 del,这样才能强制GC去删除该对象。

  • 相关阅读:
    springboot 整合 pagehelper
    Linux maven安装
    linux 查看端口状态
    mysql执行顺序
    Java int/int 保留2位小数
    【每日一题】30.储物点的距离 (区间处理,前缀和/线段树//树状数组)
    【每日一题】29.maze (BFS 进阶)
    2016年第七届 蓝桥杯C组 C/C++决赛题解
    2016年第七届 蓝桥杯A组 C/C++决赛题解
    第六届蓝桥杯C++A组 A~F题题解
  • 原文地址:https://www.cnblogs.com/johnonsoftware/p/2933178.html
Copyright © 2020-2023  润新知