Вот что у меня так далеко.Единственная проблема заключается в том, что pyqtSignal-декоратор, похоже, получает что-то из трассировки стека, и я не знаю, как это можно переопределить, что является явным недостатком PyQt-дизайна.
#!/usr/bin/env python
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from functools import wraps
import signal
import sys
signal.signal(signal.SIGINT, signal.SIG_DFL)
class SetAdder:
def __init__(self):
self.clear()
def clear(self):
self.value = set()
def aggregate(self, other):
send = not self.value
self.sent = True
self.value.add(other)
return send
# This class decorator adds nameSlot, nameAuxSignal, nameAuxSlot, and
# name_manager. Signals should be connected to nameSlot. They will cause
# the function 'name' to be called with aggregated values.
def aggregated_slot_class_decorator(list_):
def class_decorator(cls):
for manager_type, name, *args in list_:
signal_name = name + "AuxSignal"
slot_a_name = name + "Slot"
slot_b_name = name + "AuxSlot"
manager_name = name + "_manager"
def slot_a(self, *args_):
manager = getattr(self, manager_name)
if manager.aggregate(*args_):
print("Sending")
getattr(self, signal_name).emit()
def slot_b(self):
manager = getattr(self, manager_name)
getattr(self, name)(manager.value)
manager.clear()
setattr(cls, slot_a_name,
pyqtSlot(cls, *args, name=slot_a_name)(slot_a))
setattr(cls, slot_b_name,
pyqtSlot(cls, name=slot_b_name)(slot_b))
orig_init = cls.__init__
def new_init(self, *args_, **kwargs):
orig_init(self, *args_, **kwargs)
getattr(self, signal_name).connect(getattr(self, slot_b_name),
Qt.QueuedConnection)
setattr(self, manager_name, manager_type())
cls.__init__ = new_init
#setattr(cls, signal_name, pyqtSignal())
return cls
return class_decorator
@aggregated_slot_class_decorator([(SetAdder, 'test', int)])
class A(QObject):
def __init__(self):
super().__init__()
testAuxSignal = pyqtSignal()
def test(self, value):
print("Received", value)
class B(QObject):
signal = pyqtSignal(int)
a = A()
b = B()
b.signal.connect(a.testSlot)
for i in range(10):
b.signal.emit(i % 5)
app = QApplication(sys.argv)
sys.exit(app.exec_())
Выводы:
Sending
Received {0, 1, 2, 3, 4}