A purely Python implementation of the Qt signal system with no QObject dependencies
MIT License
Deprecated: I realize this library is used by a few people, but due to contractual limitations, I cannot currently maintain it. I recommend forking and developing the fork if possible. I apologize for the inconvenience.
For prior contributions to this repo, I made my contributions/submissions to this project solely in my personal capacity and am not conveying any rights to any intellectual property of any third parties.
A Qt style signal implementation that doesn't require QObjects. This supports class methods, functions, lambdas and partials.
Signals can either be created on the instance or on the class, and can be handled either as objects or by string name. Unlike PyQt signals, PySignals do not enforce types by default as I believe this is more pythonic.
Available under the MIT license.
Check out my website too for more programming and film related content: http://dgovil.com/
You can install this using pip, though the version on Pypi is outdated
pip install PySignal
This is compatible with Python 2.7+ and 3.x
def greet(name):
print "Hello,", name
class Foo(object):
started = ClassSignal()
classSignalFactory = ClassSignalFactory()
classSignalFactory.register('Greet')
def __init__(self):
super(Foo, self).__init__()
self.started.connect(greet)
self.started.emit('Watson')
self.signalFactory = SignalFactory()
self.signalFactory.register('Greet')
self.signalFactory['Greet'].connect(greet)
self.signalFactory['Greet'].emit('Sherlock')
self.classSignalFactory['Greet'].connect(greet)
self.classSignalFactory['Greet'].emit('Moriarty')
ended = Signal()
ended.connect(greet)
ended.emit('Mycroft')
foo = Foo()
# Hello, Watson
# Hello, Sherlock
# Hello, Moriarty
# Hello, Mycroft
There are 4 types of Signals included
Signal
is the base implementation of the Signal and can be created on a per instance level.ClassSignal
is an object that can be created as a class variable and will act like a signal.SignalFactory
allows you to have a single signal object on your instance that can generate signals by name.ClassSignalFactory
is the same as a signal factory but lives on the class instead of the instance.Signals allow for creating a callback interface on your object and allows for it to be extended without needing to make a new inherited class.
For example I can define the following
class Foo(object):
started = ClassSignal()
ended = ClassSignal()
def run(self):
self.started.emit()
# Do my logic here
self.ended.emit()
This does a few things:
For example:
foo1 = Foo()
foo2 = Foo()
foo1.started.connect(lambda: print("I am foo1"))
foo2.started.connect(lambda: print(42))
foo1.run() # will output I am foo1
foo2.run() # will output 42
We can also get the Signal's "sender" - the bound method responsible for emitting the signal, if available.
For example:
bar_run1 = foo1.started.sender() # will output <bound method Foo.run of <__main__.Foo object at ...>>
bar_run2 = foo2.started.sender() # will output <bound method Foo.run of <__main__.Foo object at ...>>
print(bar_run1 == foo1.run) # will output True
print(bar_run1 == foo2.run) # will output False
print(bar_run1 == bar_run2) # will output False
Instead of having to subclass Foo
and implement the new behavior, we can simply reuse the existing Foo class and attach on to its instances.
The goal of this library is to mimic Qt's callback system without requiring all either end of the signal/slot to be a QObject derivative.
That said in the current state it is missing the following features:
self
as the first parameter of the signal. e.g. signal.emit(self, arg1, arg2)
and the slot will need to expect the first argument to be the sender.If anyone has any suggestions or solutions on how I can overcome these caveats, I'm all ears and very willing to implement it or accept pull requests from other people too
There are a few other libraries to compare with that implement Signals. I am not completely familiar with them so please correct me if I am wrong. These may serve your purposes better depending on what you are doing. The goal of PySignal is first and foremost to be a Qt style signal slot system so the comparisons are written with that in mind.
Blinker appears to implement a very similar signal to slot mechanism. It is inspired by the django signal system.
SmokeSignal is another django inspired signal system.
http://www.codeheadwords.com/2015/05/05/emulating-pyqt-signals-with-descriptors
Many thanks to: