title: Custom pyqtSignal implementation
body: <p>In PyQt, you can use <code>QtCore.pyqtSignal()</code> to create custom signals. </p>
  
  <p>I tried making my own implementation of the Observer pattern in place of <code>pyqtSignal</code> to circumvent some of its limitations (e.g. no dynamic creation).</p>
  
  <p>It works for the most part, with at least one difference.</p>
  
  <p><strong>Here is my implementation so far</strong></p>
  
  <pre><code>class Signal:   
      def __init__(self):
          self.__subscribers = []
  
      def emit(self, *args, **kwargs):
          for subs in self.__subscribers:
              subs(*args, **kwargs)
  
      def connect(self, func):
          self.__subscribers.append(func)  
  
      def disconnect(self, func):  
          try:  
              self.__subscribers.remove(func)  
          except ValueError:  
              print('Warning: function %s not removed from signal %s'%(func,self))
  </code></pre>
  
  <p>The one thing noticed was a difference in how <code>QObject.sender()</code> works.</p>
  
  <p>I generally stay clear of <code>sender()</code>, but if it works differently then so may other things.</p>
  
  <p>With regular <code>pyqtSignal</code> signals, the sender is always the widget closest in a chain of signals.</p>
  
  <p>In the example at the bottom, you'll see two objects, <code>ObjectA</code> and <code>ObjectB</code>. <code>ObjectA</code> forwards signals from <code>ObjectB</code> and is finally received by Window.</p>
  
  <p>With <code>pyqtSignal</code>, the object received by <code>sender()</code> is <code>ObjectA</code>, which is the one forwarding the signal from <code>ObjectB</code>.</p>
  
  <p>With the Signal class above, the object received is instead <code>ObjectB</code>, the first object in the chain.</p>
  
  <p>Why is this?</p>
  
  <p><strong>Full example</strong></p>
  
  <pre><code># Using PyQt5 here although the same occurs with PyQt4
  
  from PyQt5.QtCore import *
  from PyQt5.QtGui import *
  from PyQt5.QtWidgets import *
  
  class Window(QWidget):
      def __init__(self, parent=None):
          super(Window, self).__init__(parent)
  
          object_a = ObjectA(self)
          object_a.signal.connect(self.listen)
  
          layout = QBoxLayout(QBoxLayout.TopToBottom, self)
          layout.addWidget(object_a)
  
      def listen(self):
          print(self.sender().__class__.__name__)
  
  
  class ObjectA(QWidget):
      signal = Signal()
      # signal = pyqtSignal()
      def __init__(self, parent=None):
          super(ObjectA, self).__init__(parent)
  
          object_b = ObjectB()
          object_b.signal.connect(self.signal.emit)
  
          layout = QBoxLayout(QBoxLayout.TopToBottom, self)
          layout.addWidget(object_b)
  
  
  class ObjectB(QPushButton):
      signal = Signal()
      # signal = pyqtSignal()
      def __init__(self, parent=None):
          super(ObjectB, self).__init__('Push me', parent)
          self.pressed.connect(self.signal.emit)
  
  if __name__ == '__main__':
      import sys
  
      app = QApplication([])
  
      win = Window()
      win.show()
  
      sys.exit(app.exec_())
  </code></pre>
  
  <p><a href="http://trevorius.com/scrapbook/python/binding-singals-dynamically/#respond">More reference</a></p>
  
  <p><strong>Edit:</strong></p>
  
  <p>Apologies, I should have provided a use-case.</p>
  
  <p>Here are some of the limitations of using pyqtSignals:</p>
  
  <p>pyqtSignal:</p>
  
  <ol>
  <li>..only works with class attributes </li>
  <li>..cannot be used in an already instantiated class </li>
  <li>..must be pre-specified with the data-types you wish to emit </li>
  <li>..produces signals that does not support keyword arguments and</li>
  <li>..produces signals that cannot be modified after instantiation</li>
  </ol>
  
  <p>Thus my main concern is using it together with baseclasses.</p>
  
  <p>Consider the following.</p>
  
  <p>6 different widgets of a list-type container widget share the same interface, but look and behave slightly different. A baseclass provides the basic variables and methods, along with signals.</p>
  
  <p>Using pyqtSignal, you would have to first inherit your baseclass from at least QObject or QWidget.</p>
  
  <p>The problem is neither of these can be use in as mix-ins or in multiple inheritance, if for instance one of the widgets also inherits from QPushButton.</p>
  
  <pre><code>class PinkListItem(QPushButton, Baseclass)
  </code></pre>
  
  <p>Using the Signal class above, you could instead make baseclasses without any previously inherited classes (or just object) and then use them as mix-ins to any derived subclasses.</p>
  
  <p>Careful not to make the question about whether or not multiple inheritance or mix-ins are good, or of other ways to achieve the same thing. I'd love your feedback on that as well, but perhaps this isn't the place.</p>
  
  <p>I would be much more interested in adding bits to the Signal class to make it work similar to what pyqtSignal produces.</p>
  
  <p><strong>Edit 2:</strong></p>
  
  <p>Just noticed a down-vote, so here comes some more use cases.</p>
  
  <p><strong>Key-word arguments when emitting.</strong></p>
  
  <pre><code>signal.emit(5)
  </code></pre>
  
  <p>Could instead be written as</p>
  
  <pre><code>signal.emit(velocity=5)
  </code></pre>
  
  <p><strong>Use with a Builder or with any sort of dependency injection</strong></p>
  
  <pre><code>def create(type):
    w = MyWidget()
    w.my_signal = Signal()
    return w
  </code></pre>
  
  <p><strong>Looser coupling</strong></p>
  
  <p>I'm using both PyQt4 and PyQt5. With the Signal class above, I could produce baseclasses for both without having it depend on either.</p>