Package pyforms :: Package gui :: Module PyFormsStateMachine |
[hide private]
[frames] | no frames]

# Source Code for Module pyforms.gui.PyFormsStateMachine

      1  import sys, glob, os
      2  from PyQt4 import uic
      3  from PyQt4 import QtGui, QtCore
      4  import pyforms.Utils.tools as tools, time
      5  from pyforms.gui.BaseWidget import BaseWidget
      6
      7  from pyStateMachine.States.State import State, EndState
      8  from pyStateMachine.StateMachineControllers.StatesController import StatesController
      9
     10
     11 -def gotoAppState(true=None, false=None, trueParms={}, falseParms={}):
     12          def go2decorator(func):
     13                  def func_wrapper(self, inVar): return func(self, inVar)
     14
     15                  func_wrapper.trueParms          = trueParms
     16                  func_wrapper.falseParms         = falseParms
     17                  func_wrapper.go2StateTrue       = true
     18                  func_wrapper.go2StateFalse      = false
     19                  func_wrapper.label = func.__name__ if func.__doc__==None else '\n'.join([x for x in func.__doc__.replace('\t','').split('\n') if len(x)>0])
     20                  return func_wrapper
     21          return go2decorator
     22
     23
     24 -class PyFormsState(State):
     25
     26 -        def init(self): pass
     27
     28 -        def enter(self, inVar, currentState={}): return inVar
     29
     30 -        def leave(self, inVar, currentState={}): return inVar
     31
     32 -        def execute(self):
     33                  if self.app!=None and hasattr(self.app, 'execute'): self.app.execute()
     34
     35          @property
     36 -        def app(self): return self._app if hasattr(self, '_app') else None
     37
     38          @app.setter
     39 -        def app(self, value): self._app = value
     40
     41
     42 -        def initForm(self):
     43                  if hasattr(self, 'app') and self.app: self.app.initForm();
     44
     45          @property
     46 -        def form(self): return self.app.form if self.app else None
     47
     48
     49
     50 -class PyFormsStateMachine(StatesController, BaseWidget):
     51
     52 -        def __init__(self, title):
     53                  BaseWidget.__init__(self, title)
     54                  StatesController.__init__(self, self.STATES)
     55                  for stateName, state in self.states.items():
     56                          if hasattr(state, 'init'): state.init()
     57
     58
     59
     60
     61 -        def initForm(self):
     62                  tabs = QtGui.QTabWidget(self)
     63                  self.layout().addWidget(tabs)
     64                  self.layout().setMargin(0)
     65                  self.layout().setSpacing(0)
     66
     67                  # Generates and load the State machine graph
     68                  self.exportGraph()
     69                  self._image = QtGui.QLabel()
     70                  self._image.setPixmap(QtGui.QPixmap('stateMachine.png'))
     71                  scrollArea = QtGui.QScrollArea();
     72                  scrollArea.setWidget(self._image);
     73                  tabs.addTab(scrollArea, 'State Machine Diagram')
     74
     75                  # Load the applications
     76                  for fromStateName, state in reversed( self.states.items() ):
     77                          if hasattr(state, 'app') and state.app:
     78                                  #Override the original application formset if the state has a new one
     79                                  state.initForm();
     80                                  # Add the application form to a new Tab
     81                                  tabs.addTab(state.form, fromStateName)
     82
     83
     84
     85
     86
     87 -        def iterateStates(self):
     88                  """
     89                  Iterate states - each call go to another level
     90                  """
     91                  if len(self._waitingStates)>0:
     92                          statesOutputs = []
     93                          print self._waitingStates
     94
     95                          #First run all the pending states
     96                          for fromStateName, toStateName, inputParam in self._waitingStates:
     97                                  state                           = self._states[toStateName]
     98                                  copyOfCurrentState      = dict(self._currentState)
     99
    100                                  if isinstance(state, EndState): executionDetails = (toStateName, state, inputParam )
    101                                  else:
    102                                          p = state.enter(inputParam, copyOfCurrentState)
    103                                          state.execute()
    104                                          outParam = state.leave(p, copyOfCurrentState)
    105                                          executionDetails = (toStateName, state, outParam )
    106
    107                                  statesOutputs.append( executionDetails )
    108
    109                          #Check the events of each exectuted state:
    110                          for stateName, state, output in statesOutputs:
    111                                  #Remove the exectued state from the waiting queue
    112                                  self._waitingStates.pop(0)
    113                                  #Check each event
    114                                  for e in state.events:
    115                                          #Select the next state to go
    116                                          go2State = e.go2StateTrue if e(state, output) else e.go2StateFalse
    117                                          #In case the state is None, it stops the state execution
    118                                          if go2State!=None:  self._waitingStates.append( [stateName, go2State, output] )
    119                                          else:                           self._waitingStates.append( [stateName, 'EndState', output] )
    120
    121                          "Save the currentState of the iteration"
    122                          self._currentState = self.__returnCurrentStatesValues()
    123                  else:
    124                          print("State machine ended")
    125
    126
    127
    128 -        def execute(self):
    129                  # Initiate the parameters set by the user
    130                  self._currentState = self.__returnCurrentStatesValues()
    131
    132                  # Iterate the states execution
    133                  while not self.ended:  self.iterateStates()
    134
    135
    136 -        def __returnCurrentStatesValues(self):
    137                  """
    138                  Iterate all the states and save the values of their controls
    139                  """
    140                  currentState = {}
    141                  for stateName, state in reversed( self.states.items() ):
    142                          appState = {}
    143                          #The state has an application associated to it
    144                          if hasattr(state, 'app') and state.app:
    145                                  for controlName, control in state.app.formControls.items():
    146                                          appState[controlName] = control.value
    147                          currentState[stateName] = appState
    148                  return currentState
    149
    150
    151
    152
    153
    154
    155
    156
    157 -def startApp(states):
    158          app = QtGui.QApplication(sys.argv)
    159          container = Container(states)
    160          app.exec_()
    161