Hi Aravind,
I had a similar issue: I wanted to execute some generic code on core.quit() calls.
I did some monkey patching. Note that it’s definitively bad practice, but it works.
I created an external module (let’s say utilities.py):
from psychopy import core
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
class OnPsychoPyQuit(object):
__metaclass__ = Singleton
IGNORE_NO = 0
IGNORE_ALL = 1
IGNORE_CORE_QUIT = 2
_IGNORE_VALUES = (IGNORE_NO, IGNORE_ALL, IGNORE_CORE_QUIT)
def __init__(self, myQuitFunction = (core.quit,(),{})):
super(OnPsychoPyQuit, self).__init__()
self._functions = []
self._myQuit = tuple(myQuitFunction)
self._coreQuit = None
self._ignoreQuit = self.IGNORE_NO
self._stack = []
def _quit(self):
if self._ignoreQuit == self.IGNORE_ALL:
return
for f in self._functions:
try:
f[1](*f[2],**f[3])
except Exception, e:
print 'Error calling quit callback: %s' %str(e)
if self._ignoreQuit != self.IGNORE_CORE_QUIT:
self._myQuit[0](*self._myQuit[1], **self._myQuit[2])
@property
def coreQuit(self):
return self._coreQuit
@property
def quitFunction(self):
return self._myQuit
def setQuitFunction(self, f, *args, **kwargs):
self._myQuit = (f, args, kwargs)
@property
def ignore(self):
return self._ignoreQuit
@ignore.setter
def ignore(self, v):
if not v in self._IGNORE_VALUES:
raise ValueError('Value not in %s' %str(self._IGNORE_VALUES))
self._ignoreQuit = v
def pushRegistry(self):
if len(self._functions):
self._stack.append((self._ignoreQuit, self._functions[:]))
def popRegistry(self):
if len(self._stack):
self._ignoreQuit, self._functions = self._stack.pop(-1)
def replace(self):
if self._coreQuit == None:
self._coreQuit = core.quit
core.quit = self._quit
def restore(self):
if self._coreQuit != None:
core.quit = self._coreQuit
def register(self, name, cb, *args, **dargs):
self._functions.append((name, cb, args, dargs))
def unregister(self, *args):
if len(args):
functions = [ f for f in self._functions if f[0] not in args ]
self._functions = functions
else:
self._functions = []
Then from inside a code component in the psychopy script, I just do:
from utilities.py import OnPsychoPyQuit
def myFunction(arg1, arg2):
print 'User pressed ESCAPE: bailing out...'
OnPsychoPyQuit().replace()
OnPsychoPyQuit().register('My function', myFunction, arg1, arg2)
...
OnPsychoPyQuit().unregister('My function')
Note that you can also do:
OnPsychoPyQuit().pushRegistry()
OnPsychoPyQuit().register('My function1', myFunction1)
OnPsychoPyQuit().register('My function2', myFunction2)
OnPsychoPyQuit().register('My function3', myFunction3)
OnPsychoPyQuit().register('My function4', myFunction4)
...
OnPsychoPyQuit().popRegistry()