ever wondered why something like this wont work when using python-clutter?
import clutter def add_effect(obj): tl = clutter.Timeline(fps=60, duration=1000) alpha = clutter.Alpha(tl, clutter.sine_inc_func) bhv = clutter.BehaviourOpacity(alpha=alpha, opacity_start=0, opacity_end=255) bhv.apply(obj) return tl def main(): re = clutter.Rectangle() tl = add_effect(re) tl.start() clutter.main()
The problem is that once the function add_effect finishes, the variables tl, alpha and bhv will get garbage collected by python because they get out of scope. But they are still needed by clutter, which results in the error. To solve this you have to keep a reference to the variables somewhere, like
import clutter tl, alpha, bhv = None, None, None def add_effect(obj): global tl, alpha, bhv tl = clutter.Timeline(fps=60, duration=1000) alpha = clutter.Alpha(t1, clutter.sine_inc_func) bhv = clutter.BehaviourOpacity(alpha=alpha, opacity_start=0, opacity_end=255) bhv.apply(obj) return tl def main(): re = clutter.Rectangle() tl = add_effect(re) tl.start() clutter.main()
of course this way you can only have one effect at a time, so using objects for encapsulating the references would is preferable.
How is this specific to clutter? Wouldn’t this happen any time you have to deal with scope? Or does Python’s implementation of scope deviate widely from every other language?
well generally you don’t have to deal with scope in python, since the garbage collector figures out when to clean up the variable on its own. This is done by reference counting.
But in the example above it fails, because the reference count of alpha is not increased when creating the Behaviour and the reference count of Behaviour is not increased when applying it to obj.
So basically this is an error in the python binding of clutter.
Interesting. The only garbage collected language I’m used to is Java, so the example of how to make it work looked perfectly natural to me.