Custom pyqtSignal implementation
Question: In PyQt, you can use `QtCore.pyqtSignal()` to create custom signals.

I tried making my own implementation of the Observer pattern in place of
`pyqtSignal` to circumvent some of its limitations (e.g. no dynamic creation).

It works for the most part, with at least one difference.

**Here is my implementation so far**

    
    
    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))
    

The one thing noticed was a difference in how `QObject.sender()` works.

I generally stay clear of `sender()`, but if it works differently then so may
other things.

With regular `pyqtSignal` signals, the sender is always the widget closest in
a chain of signals.

In the example at the bottom, you'll see two objects, `ObjectA` and `ObjectB`.
`ObjectA` forwards signals from `ObjectB` and is finally received by Window.

With `pyqtSignal`, the object received by `sender()` is `ObjectA`, which is
the one forwarding the signal from `ObjectB`.

With the Signal class above, the object received is instead `ObjectB`, the
first object in the chain.

Why is this?

**Full example**

    
    
    # 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_())
    

[More reference](http://trevorius.com/scrapbook/python/binding-singals-
dynamically/#respond)

**Edit:**

Apologies, I should have provided a use-case.

Here are some of the limitations of using pyqtSignals:

pyqtSignal:

  1. ..only works with class attributes 
  2. ..cannot be used in an already instantiated class 
  3. ..must be pre-specified with the data-types you wish to emit 
  4. ..produces signals that does not support keyword arguments and
  5. ..produces signals that cannot be modified after instantiation

Thus my main concern is using it together with baseclasses.

Consider the following.

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.

Using pyqtSignal, you would have to first inherit your baseclass from at least
QObject or QWidget.

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.

    
    
    class PinkListItem(QPushButton, Baseclass)
    

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.

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.

I would be much more interested in adding bits to the Signal class to make it
work similar to what pyqtSignal produces.

**Edit 2:**

Just noticed a down-vote, so here comes some more use cases.

**Key-word arguments when emitting.**

    
    
    signal.emit(5)
    

Could instead be written as

    
    
    signal.emit(velocity=5)
    

**Use with a Builder or with any sort of dependency injection**

    
    
    def create(type):
      w = MyWidget()
      w.my_signal = Signal()
      return w
    

**Looser coupling**

I'm using both PyQt4 and PyQt5. With the Signal class above, I could produce
baseclasses for both without having it depend on either.


Answer: You can do this with a metaclass that inherits from `pyqtWrapperType`. Inside
`__new__`, call `pyqtSignal()` as needed and set the attributes on the result
class.

