def run_macro(self, par_str_list, asynch=False): if isinstance(par_str_list, (str, unicode)): par_str_list = par_str_list, if not hasattr(self, "Output"): import sys import logging Logger.addLevelName(15, "OUTPUT") def output(loggable, msg, *args, **kw): loggable.getLogObj().log(Logger.Output, msg, *args, **kw) Logger.output = output Logger.disableLogOutput() Logger.setLogLevel(Logger.Output) #filter = taurus.core.util.LogFilter(level=Logger.Output) formatter = logging.Formatter(fmt="%(message)s") Logger.setLogFormat("%(message)s") handler = logging.StreamHandler(stream=sys.stdout) #handler.addFilter(filter) Logger.addRootLogHandler(handler) #handler.setFormatter(formatter) #logger.addHandler(handler) #logger.addFilter(filter) self.__logging_info = handler, filter, formatter # result of a macro #Logger.addLevelName(18, "RESULT") return self.macro_executor.run(par_str_list, asynch=asynch)
def main(): from taurus.core.util.log import Logger from taurus.qt.qtgui.util import TaurusWidgetFactory Logger.setLogLevel(Logger.Debug) _log = Logger(__name__) try: wf = TaurusWidgetFactory() klasses = wf.getWidgetClasses() ok_nb, skipped_nb, e1_nb, e2_nb, e3_nb, e4_nb = 0, 0, 0, 0, 0, 0 for widget_klass in klasses: name = widget_klass.__name__ #_log.debug("Processing %s" % name) if name in _SKIP: #_log.debug("Skipped %s" % name) skipped_nb += 1 continue # if getQtDesignerPluginInfo does not exist, returns None or raises # an exception: forget the widget cont = False try: qt_info = widget_klass.getQtDesignerPluginInfo() if qt_info is None: #_log.debug("E1: Canceled %s (getQtDesignerPluginInfo)" % name) e1_nb += 1 cont = True except AttributeError: #_log.debug("E2: Canceled %s (widget doesn't have getQtDesignerPluginInfo())" % name) e2_nb += 1 cont = True except Exception, e: #_log.debug("E3: Canceled %s (%s)" % (name, str(e))) e3_nb += 1 cont = True if cont: continue for k in ('module', ): if not qt_info.has_key(k): #_log.debug("E4: Canceled %s (getQtDesignerPluginInfo doesn't have key %s)" % (name, k)) e4_nb += 1 cont = True if cont: continue plugin_klass = build_qtdesigner_widget_plugin(widget_klass) plugin_klass_name = plugin_klass.__name__ globals()[plugin_klass_name] = plugin_klass _plugins[plugin_klass_name] = plugin_klass ok_nb += 1 #_log.debug("DONE processing %s" % name) _log.info("Inpected %d widgets. %d (OK), %d (Skipped), %d (E1), %d (E2), %d (E3), %d(E4)" % ( len(klasses), ok_nb, skipped_nb, e1_nb, e2_nb, e3_nb, e4_nb)) _log.info("E1: getQtDesignerPluginInfo() returns None") _log.info("E2: widget doesn't implement getQtDesignerPluginInfo()") _log.info("E3: getQtDesignerPluginInfo() throws exception") _log.info( "E4: getQtDesignerPluginInfo() returns dictionary with missing key (probably 'module' key)")
class BaseControllerTestCase(object): """ Base test case for unit testing arbitrary controllers. This class will create a controller instance and define an axis from the class member attributes: KLASS <type> controller class PROPS <dict> properties of the controller AXIS <int> number of the axis """ KLASS = None PROPS = {} AXIS = 1 DEBUG = False def setUp(self): self.logger = Logger('BaseControllerTestCase') if self.DEBUG: self.logger.setLogLevel(Logger.Debug) if self.KLASS is None: raise Exception('Ctrl klass has not been defined') name = 'test_ctrl' self.ctrl = self.KLASS(name, self.PROPS) self.pre_AddDevice_hook() self.ctrl.AddDevice(self.AXIS) def tearDown(self): if self.ctrl is not None: self.ctrl.DeleteDevice(self.AXIS) def axisPar(self, name, value, expected_value=None): """ Helper for test the SetAxisPar & GetaxisPar methods """ axis = self.AXIS if expected_value is None: expected_value = value self.ctrl.SetAxisPar(axis, name, value) r_value = self.ctrl.GetAxisPar(axis, name) msg = ('The %s value is %s, and the expected value is %s' % (name, r_value, expected_value)) self.assertEqual(r_value, expected_value, msg) def stateOne(self, expected_state=State.On): """ Helper for test the stateOne method """ sta, status = self.ctrl.StateOne(self.AXIS) msg = ('The current state of axis(%d) is %d when expected, %d' % (self.AXIS, sta, expected_state)) self.assertEqual(sta, expected_state, msg) def start_action(self, configuration): """ This method set the axis parameters and pre start the axis. """ for key, value in configuration.items(): self.axisPar(key, value) self.ctrl.SynchOne(configuration) def pre_AddDevice_hook(self): pass
class TaurusEmitterThread(Qt.QThread): """ The TaurusEmitterThread Class ========================== This object get items from a python Queue and performs a thread safe operation on them. It is useful to serialize Qt tasks in a background thread. :param parent: a Qt/Taurus object :param name: identifies object logs :param queue: if None parent.getQueue() is used, if not then the queue passed as argument is used :param method: the method to be executed using each queue item as argument :param cursor: if True or QCursor a custom cursor is set while the Queue is not empty How TaurusEmitterThread works -------------------------- TaurusEmitterThread is a worker thread that processes a queue of iterables passed as arguments to the specified method every time that ``doSomething()`` is called: * ``self.method(*item)`` will be called if TaurusEmitterThread.method has been initialized. * ``item[0](item[1:])`` will be called if ``method`` is not initialized and the first element of the queued iterable is *callable*. TaurusEmitterThread uses two queues: * ``self.queue`` manages the objects added externally: + the ``next()`` method passes objects from ``self.queue`` to ``self.todo queue`` + every time that a *somethingDone* signal arrives ``next()`` is called. + ``next()`` can be called also externally to ensure that the main queue is being processed. + the queue can be accessed externally using ``getQueue()`` + ``getQueue().qsize()`` returns number of remaining objects in queue. + while there are objects in queue the ``.next()`` method will override applications cursor. a call to ``next()`` with an empty queue will restore the original cursor. * ``self.todo`` is managed by the ``run()/start()`` method: - a loop waits continuously for new objects in ``self.todo`` queue. - if an object is found, it is sent in a *doSomething* signal. - if *"exit"* is found the loop exits. Usage example ------------- .. code-block:: python #Applying TaurusEmitterThread to an existing class: from queue import Queue from functools import partial def modelSetter(args): obj,model = args[0],args[1] obj.setModel(model) klass TaurusGrid(Qt.QFrame, TaurusBaseWidget): ... def __init__(self, parent = None, designMode = False): ... self.modelsQueue = Queue() self.modelsThread = TaurusEmitterThread(parent=self, queue=self.modelsQueue,method=modelSetter ) ... def build_widgets(...): ... previous,synoptic_value = \ synoptic_value,TaurusValue(cell_frame) #synoptic_value.setModel(model) self.modelsQueue.put((synoptic_value,model)) ... def setModel(self,model): ... if hasattr(self,'modelsThread') and \ not self.modelsThread.isRunning(): self.modelsThread.start() elif self.modelsQueue.qsize(): self.modelsThread.next() ... """ def __init__(self, parent=None, name='', queue=None, method=None, cursor=None, sleep=5000, polling=0, loopwait=5): """ Parent must be not None and must be a TaurusGraphicsScene! :param queue: pass an external action queue (optional) :param method: action processor (e.g. modelSetter) :param cursor: QCursor during process (optional) :param sleep: delay in ms before thread start :param polling: process actions at fix period (milliseconds) :param loopwait: wait N milliseconds between actions """ Qt.QThread.__init__(self, parent) self.name = name self.log = Logger('TaurusEmitterThread(%s)' % self.name) self.log.setLogLevel(self.log.Info) self.queue = queue or Queue() self.todo = Queue() self.method = method self.cursor = Qt.QCursor( Qt.Qt.WaitCursor) if cursor is True else cursor self._cursor = False self.timewait = int(sleep) self.polling = int(polling) self.loopwait = int(loopwait) if self.polling: self.refreshTimer = Qt.QTimer() self.refreshTimer.timeout.connect(self.onRefresh) else: self.refreshTimer = None self.emitter = QEmitter() self.emitter.moveToThread(Qt.QApplication.instance().thread()) # Mandatory!!! if parent is set before changing thread it could lead to # segFaults! self.emitter.setParent(Qt.QApplication.instance()) self._done = 0 # Moved to the end to prevent segfaults ... self.emitter.doSomething.connect(self._doSomething) if not self.refreshTimer: self.emitter.somethingDone.connect(self.next) def onRefresh(self): try: size = self.getQueue().qsize() if size: self.log.info('onRefresh(%s)' % size) self.next() else: self.log.debug('onRefresh()') except: self.log.warning(traceback.format_exc()) def getQueue(self): if self.queue: return self.queue elif hasattr(self.parent(), 'getQueue'): self.parent().getQueue() else: return None def getDone(self): """ Returns % of done tasks in 0-1 range """ pending = self.getQueue().qsize() return float(self._done) / (self._done + pending) def clear(self): while not self.todo.empty(): self.todo.get() while not self.getQueue().empty(): self.getQueue().get() self._done += 1 def purge(self, obj): """ Remove a given object from all queues """ nqueue = Queue() while not self.todo.empty(): i = self.todo.get() if obj not in i: nqueue.put(i) while not self.queue.empty(): i = self.queue.get() if obj not in i: nqueue.put(i) while not nqueue.empty(): self.queue.put(nqueue.get()) self.next() def _doSomething(self, params): self.log.debug('At TaurusEmitterThread._doSomething(%s)' % str(params)) if not self.method: method, args = params[0], params[1:] else: method, args = self.method, params if method: try: method(*args) except: self.log.error( 'At TaurusEmitterThread._doSomething(%s): \n%s' % (list(map(str, args)), traceback.format_exc())) self.emitter.somethingDone.emit() self._done += 1 return def next(self): queue = self.getQueue() msg = ('At TaurusEmitterThread.next(), %d items remaining.' % queue.qsize()) if (queue.empty() and not self.polling): self.log.info(msg) else: self.log.debug(msg) try: if not queue.empty(): if not self._cursor and self.cursor is not None: Qt.QApplication.instance().setOverrideCursor( Qt.QCursor(self.cursor)) self._cursor = True # A blocking get here would hang the GUIs!!! item = queue.get(False) self.todo.put(item) self.log.debug('Item added to todo queue: %s' % str(item)) elif self._cursor: Qt.QApplication.instance().restoreOverrideCursor() self._cursor = False except Empty: self.log.warning(traceback.format_exc()) pass except: self.log.warning(traceback.format_exc()) return def run(self): Qt.QApplication.instance().thread().msleep(self.timewait) self.log.info('#' * 80) self.log.info('At TaurusEmitterThread.run()') self.next() if self.refreshTimer: self.refreshTimer.start(self.polling) while True: self.log.debug('At TaurusEmitterThread.run() loop.') item = self.todo.get(True) if isString(item): if item == "exit": break else: continue self.log.debug('Emitting doSomething signal ...') self.emitter.doSomething.emit(item) if self.loopwait: self.msleep(self.loopwait) # End of while self.log.info('#' * 80 + '\nOut of TaurusEmitterThread.run()' + '\n' + '#' * 80)
class SingletonWorker(object): """ SingletonWorker is used to manage TaurusEmitterThread as Singleton objects SingletonWorker is constructed using the same arguments than TaurusTreadEmitter ; but instead of creating a QThread for each instance it creates a single QThread for all instances. The Queue is still different for each of the instances; it is connected to the TaurusEmitterThread signals (*next()* and *somethingDone()*) and each Worker queue is used as a feed for the shared QThread. This implementation reduced the cpu of vacca application in a 50% factor. :param parent: a Qt/Taurus object :param name: identifies object logs :param queue: if None parent.getQueue() is used, if not then the queue passed as argument is used :param method: the method to be executed using each queue item as argument :param cursor: if True or QCursor a custom cursor is set while the Queue is not empty """ _thread = None def __init__(self, parent=None, name='', queue=None, method=None, cursor=None, sleep=5000, log=Logger.Warning, start=True): self.name = name self.log = Logger('SingletonWorker(%s)' % self.name) self.log.setLogLevel(log) self.log.info('At SingletonWorker.__init__(%s)' % self.name) self.parent = parent self.method = method self._running = False if SingletonWorker._thread is None: SingletonWorker._thread = TaurusEmitterThread( parent, name='SingletonWorker', cursor=cursor, sleep=sleep) self.thread = SingletonWorker._thread self.queue = queue or Queue() if start: self.start() def put(self, item, block=True, timeout=None): self.getQueue().put(item, block, timeout) def size(self): return self.getQueue().qsize() def next(self, item=None): if item is not None: self.put(item) elif self.queue.empty(): return msg = ('At SingletonWorker.next(), ' '%d items not passed yet to Emitter.' % self.queue.qsize()) self.log.info(msg) # (queue.empty() and self.log.info or self.log.debug)(msg) try: i = 0 while not self.queue.empty(): # A blocking get here would hang the GUIs!!! item = self.queue.get(False) if self.method: self.thread.getQueue().put([self.method] + list(item)) else: self.thread.getQueue().put(item) i += 1 self.log.info('%d Items added to emitter queue' % i) self.thread.emitter.newQueue.emit() except Empty: self.log.warning(traceback.format_exc()) except: self.log.warning(traceback.format_exc()) return def getQueue(self): return self.queue def getDone(self): return self.thread.getDone() def start(self): self.thread.emitter.somethingDone.connect(self.next) self.thread.emitter.newQueue.connect(self.thread.next) try: self.thread.start() except: pass self.next() self._running = True return def stop(self): self.thread.emitter.somethingDone.disconnect(self.next) self.thread.emitter.newQueue.disconnect(self.thread.next) self._running = False return def clear(self): """ This method will clear queue only if next() has not been called. If you call self.thread.clear() it will clear objects for all workers!, be careful """ while not self.queue.empty(): self.queue.get() # self.thread.clear() def purge(self, obj): """ Remove a given object from all queues """ nqueue = Queue() while not self.queue.empty(): i = self.queue.get() if obj not in i: nqueue.put(i) while not nqueue.empty(): self.queue.put(nqueue.get()) self.next() def isRunning(self): return self._running def isFinished(self): return self.thread.isFinished() def finished(self): return self.thread.finished() def started(self): return self._running def terminated(self): return self.thread.terminated() def sleep(self, s): return self.thread.sleep(s)
class TaurusEmitterThread(Qt.QThread): """ The TaurusEmitterThread Class ========================== This object get items from a python Queue and performs a thread safe operation on them. It is useful to serialize Qt tasks in a background thread. :param parent: a Qt/Taurus object :param name: identifies object logs :param queue: if None parent.getQueue() is used, if not then the queue passed as argument is used :param method: the method to be executed using each queue item as argument :param cursor: if True or QCursor a custom cursor is set while the Queue is not empty How TaurusEmitterThread works -------------------------- TaurusEmitterThread is a worker thread that processes a queue of iterables passed as arguments to the specified method every time that ``doSomething()`` is called: * ``self.method(*item)`` will be called if TaurusEmitterThread.method has been initialized. * ``item[0](item[1:])`` will be called if ``method`` is not initialized and the first element of the queued iterable is *callable*. TaurusEmitterThread uses two queues: * ``self.queue`` manages the objects added externally: + the ``next()`` method passes objects from ``self.queue`` to ``self.todo queue`` + every time that a *somethingDone* signal arrives ``next()`` is called. + ``next()`` can be called also externally to ensure that the main queue is being processed. + the queue can be accessed externally using ``getQueue()`` + ``getQueue().qsize()`` returns the number of remaining objects in queue. + while there are objects in queue the ``.next()`` method will override applications cursor. a call to ``next()`` with an empty queue will restore the original cursor. * ``self.todo`` is managed by the ``run()/start()`` method: - a loop waits continuously for new objects in ``self.todo`` queue. - if an object is found, it is sent in a *doSomething* signal. - if *"exit"* is found the loop exits. Usage example ------------- .. code-block:: python #Applying TaurusEmitterThread to an existing class: import Queue from functools import partial def modelSetter(args): obj,model = args[0],args[1] obj.setModel(model) klass TaurusGrid(Qt.QFrame, TaurusBaseWidget): ... def __init__(self, parent = None, designMode = False): ... self.modelsQueue = Queue.Queue() self.modelsThread = TaurusEmitterThread(parent=self,queue=self.modelsQueue,method=modelSetter ) ... def build_widgets(...): ... previous,synoptic_value = synoptic_value,TaurusValue(cell_frame) #synoptic_value.setModel(model) self.modelsQueue.put((synoptic_value,model)) ... def setModel(self,model): ... if hasattr(self,'modelsThread') and not self.modelsThread.isRunning(): self.modelsThread.start() elif self.modelsQueue.qsize(): self.modelsThread.next() ... """ def __init__(self, parent=None, name='', queue=None, method=None, cursor=None, sleep=5000): """ Parent most not be None and must be a TaurusGraphicsScene! """ Qt.QThread.__init__(self, parent) self.name = name self.log = Logger('TaurusEmitterThread(%s)' % self.name) self.log.setLogLevel(self.log.Info) self.queue = queue or Queue.Queue() self.todo = Queue.Queue() self.method = method self.cursor = Qt.QCursor( Qt.Qt.WaitCursor) if cursor is True else cursor self._cursor = False self.timewait = sleep self.emitter = QEmitter() self.emitter.moveToThread(Qt.QApplication.instance().thread()) # Mandatory!!! if parent is set before changing thread it could lead to # segFaults! self.emitter.setParent(Qt.QApplication.instance()) self._done = 0 # Moved to the end to prevent segfaults ... self.emitter.doSomething.connect(self._doSomething) self.emitter.somethingDone.connect(self.next) def getQueue(self): if self.queue: return self.queue elif hasattr(self.parent(), 'getQueue'): self.parent().getQueue() else: return None def getDone(self): """ Returns % of done tasks in 0-1 range """ return self._done / (self._done + self.getQueue().qsize()) if self._done else 0. def clear(self): while not self.todo.empty(): self.todo.get() while not self.getQueue().empty(): self.getQueue().get() self._done += 1 def purge(obj): nqueue = Queue.Queue() while not self.todo.empty(): i = self.todo.get() if obj not in i: nqueue.put(i) while not self.queue.empty(): i = self.queue.get() if obj not in i: nqueue.put(i) while not nqueue.empty(): self.queue.put(nqueue.get()) self.next() def _doSomething(self, params): self.log.debug('At TaurusEmitterThread._doSomething(%s)' % str(params)) if not self.method: method, args = params[0], params[1:] else: method, args = self.method, params if method: try: method(*args) except: self.log.error('At TaurusEmitterThread._doSomething(%s): \n%s' % ( map(str, args), traceback.format_exc())) self.emitter.somethingDone.emit() self._done += 1 return def next(self): queue = self.getQueue() msg = 'At TaurusEmitterThread.next(), %d items remaining.' % queue.qsize() (queue.empty() and self.log.info or self.log.debug)(msg) try: if not queue.empty(): if not self._cursor and self.cursor is not None: Qt.QApplication.instance().setOverrideCursor(Qt.QCursor(self.cursor)) self._cursor = True # A blocking get here would hang the GUIs!!! item = queue.get(False) self.todo.put(item) self.log.debug('Item added to todo queue: %s' % str(item)) elif self._cursor: Qt.QApplication.instance().restoreOverrideCursor() self._cursor = False except Queue.Empty: self.log.warning(traceback.format_exc()) pass except: self.log.warning(traceback.format_exc()) return def run(self): Qt.QApplication.instance().thread().sleep(int(self.timewait / 1000) if self.timewait > 10 else int(self.timewait)) # wait(self.sleep) self.log.info('#' * 80) self.log.info('At TaurusEmitterThread.run()') self.next() while True: self.log.debug('At TaurusEmitterThread.run() loop.') item = self.todo.get(True) if isString(item): if item == "exit": break else: continue self.log.debug('Emitting doSomething signal ...') self.emitter.doSomething.emit(item) # End of while self.log.info( '#' * 80 + '\nOut of TaurusEmitterThread.run()' + '\n' + '#' * 80)
class SingletonWorker(): # Qt.QObject): """ The SingletonWorker works ========================= The SingletonWorker class is constructed using the same arguments than the TaurusTreadEmitter class ; but instead of creating a QThread for each instance of the class it creates a single QThread for all instances. The Queue is still different for each of the instances; it is connected to the TaurusEmitterThread signals (*next()* and *somethingDone()*) and each Worker queue is used as a feed for the shared QThread. This implementation reduced the cpu of vacca application in a 50% factor. :param parent: a Qt/Taurus object :param name: identifies object logs :param queue: if None parent.getQueue() is used, if not then the queue passed as argument is used :param method: the method to be executed using each queue item as argument :param cursor: if True or QCursor a custom cursor is set while the Queue is not empty This class is used to manage TaurusEmitterThread as Singleton objects: """ _thread = None def __init__(self, parent=None, name='', queue=None, method=None, cursor=None, sleep=5000, log=Logger.Warning, start=True): self.name = name self.log = Logger('SingletonWorker(%s)' % self.name) self.log.setLogLevel(log) self.log.info('At SingletonWorker.__init__(%s)' % self.name) self.parent = parent self.method = method self._running = False if SingletonWorker._thread is None: SingletonWorker._thread = TaurusEmitterThread( parent, name='SingletonWorker', cursor=cursor, sleep=sleep) self.thread = SingletonWorker._thread self.queue = queue or Queue.Queue() if start: self.start() def put(self, item, block=True, timeout=None): self.getQueue().put(item, block, timeout) def size(self): return self.getQueue().qsize() def next(self, item=None): if item is not None: self.put(item) elif self.queue.empty(): return msg = 'At SingletonWorker.next(), %d items not passed yet to Emitter.' % self.queue.qsize() self.log.info(msg) #(queue.empty() and self.log.info or self.log.debug)(msg) try: i = 0 while not self.queue.empty(): # A blocking get here would hang the GUIs!!! item = self.queue.get(False) if self.method: self.thread.getQueue().put([self.method] + list(item)) else: self.thread.getQueue().put(item) i += 1 self.log.info('%d Items added to emitter queue' % i) self.thread.emitter.newQueue.emit() except Queue.Empty: self.log.warning(traceback.format_exc()) except: self.log.warning(traceback.format_exc()) return def getQueue(self): return self.queue def getDone(self): return self.thread.getDone() def start(self): self.thread.emitter.somethingDone.connect(self.next) self.thread.emitter.newQueue.connect(self.thread.next) try: self.thread.start() except: pass self.next() self._running = True return def stop(self): self.thread.emitter.somethingDone.disconnect(self.next) self.thread.emitter.newQueue.disconnect(self.thread.next) self._running = False return def clear(self): """ This method will clear queue only if next() has not been called. If you call self.thread.clear() it will clear objects for all workers!, be careful """ while not self.queue.empty(): self.queue.get() # self.thread.clear() def purge(obj): nqueue = Queue.Queue() while not self.queue.empty(): i = self.queue.get() if obj not in i: nqueue.put(i) while not nqueue.empty(): self.queue.put(nqueue.get()) def isRunning(self): return self._running def isFinished(self): return self.thread.isFinished() def finished(self): return self.thread.finished() def started(self): return self._running def terminated(self): return self.thread.terminated() def sleep(self, s): return self.thread.sleep(s)