Created
April 28, 2016 12:41
-
-
Save cpascual/8a90d3464f1819807746812ee56b9319 to your computer and use it in GitHub Desktop.
Wrapper to work around signal and method conflicts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SignalMethodWrapper(object): | |
"""Object that can act simultaneously as a pyqtBoundSignal and as a callable | |
method. | |
It optionally allows to log deprecation messages whe used as a signal | |
or as a method or both | |
""" | |
def __init__(self, pyqtboundsignal, method, alt_sig=None, alt_meth=None, | |
name='<wrapper>'): | |
""" | |
Init for the wrapper. | |
If alt_sig is passed, the usage of this wrapper as a signal will be | |
considered deprecated. Similarly for methods if alt_meth is passed. | |
:param pyqtboundsignal: signal to wrap | |
:param method: method to wrap | |
:param alt_sig: name of alternative signal to be suggested | |
:param alt_meth: name of alternative method to be suggested | |
:param name: name of the wrapper obj (only used for deprecation message) | |
""" | |
self._name = name | |
self._sig = pyqtboundsignal | |
self._meth = method | |
self._alt_sig = alt_sig | |
self._alt_meth = alt_meth | |
def __call__(self, *args, **kwargs): | |
if self._alt_meth: | |
from taurus.core.util.log import deprecated | |
deprecated(dep="%s method" % self._name, alt=self._alt_meth) | |
self._meth(*args, **kwargs) | |
def __getattr__(self, item): | |
if self._alt_sig: | |
from taurus.core.util.log import deprecated | |
deprecated(dep="%s signal" % self._name, alt=self._alt_sig) | |
return getattr(self._sig, item) | |
if __name__ == '__main__': | |
from taurus.external.qt import Qt | |
from taurus.qt.qtgui.application import TaurusApplication | |
import sys | |
app = TaurusApplication() | |
# Consider the following case: | |
# when using old-style signals, it is possible to | |
# have a MyObj class that uses a signal named "foo" *and* has a method | |
# named "foo". | |
# When converting to new-style signals , the signal becomes a member of the | |
# class and hence the name collides with the method. | |
# | |
# The solution is to rename *both* the signal and the method to some private | |
# names and then wrap the two of them in a SignalMethodWrapper object which | |
# is inserted as "foo" | |
class OldC(Qt.QObject): | |
"""Object using old-style signals""" | |
def foo(self, p): | |
print "OLD method _foo", p | |
def bar(self, p): | |
print "OLD method bar", p | |
def test(self): | |
# call the foo "method" directly | |
self.foo(1) | |
#connect the foo "signal" to the bar method | |
self.connect(self, Qt.SIGNAL('foo'), self.bar) | |
# connect the foo "signal" to the foo "method" !!!! | |
self.connect(self, Qt.SIGNAL('foo'), self.foo) | |
# emit "signal" foo | |
self.emit(Qt.SIGNAL('foo'), 2) | |
class NewC(Qt.QObject): | |
"""Refatored OldC using new-style signals and avooiding name conflict | |
with a SignalMethodWrapper""" | |
_fooSig = Qt.pyqtSignal(int) | |
def __init__(self): | |
Qt.QObject.__init__(self) | |
# monkey-patching injection of the fake signal | |
# note: it cannot be done at class level because C._fooSig is | |
# properly created only after instantiation of C | |
self.foo = SignalMethodWrapper(self._fooSig, self._fooMeth, | |
alt_meth='_foo', alt_sig='baz') | |
def _fooMeth(self, p): | |
print "NEW method foo", p | |
def bar(self, p): | |
print "NEW method bar", p | |
def test(self): | |
# call the foo "method" directly | |
self.foo(1) | |
#connect the foo "signal" to the bar method | |
self.foo.connect(self.bar) | |
# connect the foo "signal" to the foo "method" !!!! | |
self.foo.connect(self.foo) | |
# emit "signal" foo | |
self.foo.emit(2) | |
old = OldC() | |
new = NewC() | |
Qt.QTimer.singleShot(100, old.test) | |
Qt.QTimer.singleShot(200, new.test) | |
Qt.QTimer.singleShot(300, sys.exit) | |
sys.exit(app.exec_()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment