/ lib / python / qtvcp / core.py
core.py
  1  #!/usr/bin/env python
  2  # vim: sts=4 sw=4 et
  3  
  4  import linuxcnc
  5  import gobject
  6  
  7  import _hal, hal
  8  from PyQt5.QtCore import QObject, QTimer, pyqtSignal
  9  from hal_glib import GStat
 10  from qtvcp.qt_istat import _IStat as IStatParent
 11  
 12  # Set up logging
 13  import logger
 14  log = logger.getLogger(__name__)
 15  # log.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
 16  
 17  class QPin(hal.Pin, QObject):
 18      value_changed = pyqtSignal([int], [float], [bool] )
 19  
 20      REGISTRY = []
 21      UPDATE = False
 22  
 23      def __init__(self, *a, **kw):
 24          super(QPin, self).__init__(*a, **kw)
 25          QObject.__init__(self, None)
 26          self._item_wrap(self._item)
 27          self._prev = None
 28          self.REGISTRY.append(self)
 29          self.update_start()
 30  
 31      def update(self):
 32          tmp = self.get()
 33          if tmp != self._prev:
 34              self.value_changed.emit(tmp)
 35          self._prev = tmp
 36  
 37      @classmethod
 38      def update_all(self):
 39          if not self.UPDATE:
 40              return
 41          kill = []
 42          for p in self.REGISTRY:
 43              try:
 44                  p.update()
 45              except Exception as e:
 46                  kill.append(p)
 47                  log.error("Error updating pin {}; Removing".format(p))
 48                  log.exception(e)
 49          for p in kill:
 50              self.REGISTRY.remove(p)
 51          return self.UPDATE
 52  
 53      @classmethod
 54      def update_start(self, timeout=100):
 55          if QPin.UPDATE:
 56              return
 57          QPin.UPDATE = True
 58          self.timer = QTimer()
 59          self.timer.timeout.connect(self.update_all)
 60          self.timer.start(100)
 61  
 62      @classmethod
 63      def update_stop(self, timeout=100):
 64          QPin.UPDATE = False
 65  
 66  class QComponent:
 67      def __init__(self, comp):
 68          if isinstance(comp, QComponent):
 69              comp = comp.comp
 70          self.comp = comp
 71  
 72      def newpin(self, *a, **kw): return QPin(_hal.component.newpin(self.comp, *a, **kw))
 73      def getpin(self, *a, **kw): return QPin(_hal.component.getpin(self.comp, *a, **kw))
 74  
 75      def exit(self, *a, **kw): return self.comp.exit(*a, **kw)
 76  
 77      def __getitem__(self, k): return self.comp[k]
 78      def __setitem__(self, k, v): self.comp[k] = v
 79  
 80  ################################################################
 81  # IStat class
 82  ################################################################
 83  class Info(IStatParent):
 84      _instance = None
 85      _instanceNum = 0
 86      def __new__(cls, *args, **kwargs):
 87          if not cls._instance:
 88              cls._instance = IStatParent.__new__(cls, *args, **kwargs)
 89          return cls._instance
 90  
 91  # Now that the class is defined create a reference to it for the other classes
 92  INI = Info()
 93  
 94  ################################################################
 95  # GStat class
 96  ################################################################
 97  # use the same Gstat as gladeVCP uses
 98  # by subclassing it
 99  class Status(GStat):
100      _instance = None
101      _instanceNum = 0
102      __gsignals__ = {
103          'toolfile-stale': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
104      }
105  
106      # only make one instance of the class - pass it to all other
107      # requested instances
108      def __new__(cls, *args, **kwargs):
109          if not cls._instance:
110              cls._instance = GStat.__new__(cls, *args, **kwargs)
111          return cls._instance
112  
113      def __init__(self):
114          # only initialize once for all instances
115          if self.__class__._instanceNum >=1:
116              return
117          gobject.GObject.__init__(self)
118          self.__class__._instanceNum += 1
119          super(GStat, self).__init__()
120          self.current_jog_rate = INI.DEFAULT_LINEAR_JOG_VEL
121          self.angular_jog_velocity = INI.DEFAULT_ANGULAR_JOG_VEL
122  
123      # we override this function from hal_glib
124      #TODO why do we need to do this with qt5 and not qt4?
125      # seg fault without it
126      def set_timer(self):
127          gobject.threads_init()
128          gobject.timeout_add(100, self.update)
129  
130  
131  ################################################################
132  # Lcnc_Action class
133  ################################################################
134  from qtvcp.qt_action import _Lcnc_Action as _ActionParent
135  class Action(_ActionParent):
136      _instance = None
137      _instanceNum = 0
138      def __new__(cls, *args, **kwargs):
139          if not cls._instance:
140              cls._instance = _ActionParent.__new__(cls, *args, **kwargs)
141          return cls._instance
142  
143  ################################################################
144  # TStat class
145  ################################################################
146  from qtvcp.qt_tstat import _TStat as _TStatParent
147  
148  class Tool(_TStatParent):
149      _instance = None
150      _instanceNum = 0
151      def __new__(cls, *args, **kwargs):
152          if not cls._instance:
153              cls._instance = _TStatParent.__new__(cls, *args, **kwargs)
154          return cls._instance