Как указывают документы :
Сигнал (в частности, несвязанный сигнал) является атрибутом класса.Когда сигнал упоминается как атрибут экземпляра класса, тогда PyQt5 автоматически связывает экземпляр с сигналом, чтобы создать связанный сигнал.Это тот же механизм, который сам Python использует для создания связанных методов из функций класса.
Сигнал объявляется как атрибут класса, но при обращении через self связывается с объектом, чтоявляется, заявленный сигнал отличается от созданного сигнала:
from PyQt5 import QtCore
class Foo(QtCore.QObject):
fooSignal = QtCore.pyqtSignal()
print("declared:", fooSignal)
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
print("instantiated:", self.fooSignal)
if __name__ == '__main__':
import sys
app = QtCore.QCoreApplication(sys.argv)
obj = Foo()
Выход:
declared: <unbound PYQT_SIGNAL )>
instantiated: <bound PYQT_SIGNAL fooSignal of Foo object at 0x7f4beb998288>
Это причина ошибки, которую вы получаете, поэтому, если вы хотите использовать сигналыВы должны получить его, используя объект, чтобы мы могли проверить атрибуты и получить сигналы:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
foo = QtCore.pyqtSignal(str)
bar = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.fill_signals()
self.names = ["foo", "bar"]
self.btn_go = QtWidgets.QPushButton("Go")
self.mywidgets = {}
for name in self.names:
self.mywidgets[name] = QtWidgets.QLineEdit()
signal = self.mysignals.get(name)
if signal is not None:
signal.connect(self.mywidgets[name].setText)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.btn_go)
for name in self.names:
layout.addWidget(self.mywidgets[name])
self.btn_go.clicked.connect(self.testing)
def fill_signals(self):
self.mysignals = dict()
for p in dir(self):
attr = getattr(self, p)
if isinstance(attr, QtCore.pyqtBoundSignal):
self.mysignals[p] = attr
def testing(self):
self.foo.emit("foo")
self.bar.emit("bar")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())