Сигналы как объекты создаются каждый раз, когда вы вызываете его, поскольку они представляют другое соединение:
In [1]: import sys
In [2]: from PyQt5 import QtWidgets
In [3]: app = QtWidgets.QApplication(sys.argv)
In [4]: button = QtWidgets.QPushButton()
In [5]: id(button.clicked)
Out[5]: 140150155639464
In [6]: id(button.clicked)
Out[6]: 140150154507528
In [7]: id(button.clicked)
Out[7]: 140150155640184
In [8]: id(button.clicked)
Out[8]: 140150155640504
In [9]: id(button.clicked)
Out[9]: 140150154510128
In [10]: id(button.clicked)
Out[10]: 140149427454320
Поэтому, если вы подключаетесь 100 раз между одним и тем же сигналом и слотом, и когда сигнал излучается,слот будет вызываться 100 раз:
import sys
from PyQt5 import QtCore, QtWidgets
def foo():
print("clicked")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
button = QtWidgets.QPushButton("Press me")
button.show()
for _ in range(10):
button.clicked.connect(foo)
# the click is emulated
QtCore.QTimer.singleShot(1000, lambda: button.animateClick(500))
QtCore.QTimer.singleShot(2000, app.quit)
sys.exit(app.exec_())
Вывод:
clicked
clicked
clicked
clicked
clicked
clicked
clicked
clicked
clicked
clicked
Таким образом, будет невозможно решить вашу проблему напрямую, но я думаю, что ваша цель состоит в том, чтобы определить, какой объект испустилсигнал, который вызывает слот, поскольку у вас, вероятно, есть несколько объектов, подключенных к одному слоту, и для этого, если есть решение:
1.Использование sender()
метода
Если слот принадлежит QObject (или классам, производным от QObject в качестве виджетов), то вы можете использовать метод sender для получения объекта, испустившего сигнал.
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.button_1 = QtWidgets.QPushButton("button 1")
self.button_1.clicked.connect(self.foo)
self.button_2 = QtWidgets.QPushButton("button 2")
self.button_2.clicked.connect(self.foo)
self.button_3 = QtWidgets.QPushButton("button 3")
self.button_3.clicked.connect(self.foo)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.button_1)
lay.addWidget(self.button_2)
lay.addWidget(self.button_3)
@QtCore.pyqtSlot()
def foo(self):
button = self.sender()
if button is self.button_1:
print("button_1")
elif button is self.button_2:
print("button_2")
elif button is self.button_3:
print("button_3")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
2.Передайте объект в качестве дополнительного параметра
2,1 лямбда-функция
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.button_1 = QtWidgets.QPushButton("button 1")
self.button_1.clicked.connect(lambda *args, b=self.button_1 : self.foo(b))
self.button_2 = QtWidgets.QPushButton("button 2")
self.button_2.clicked.connect(lambda *args, b=self.button_2 : self.foo(b))
self.button_3 = QtWidgets.QPushButton("button 3")
self.button_3.clicked.connect(lambda *args, b=self.button_3 : self.foo(b))
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.button_1)
lay.addWidget(self.button_2)
lay.addWidget(self.button_3)
def foo(self, button):
if button is self.button_1:
print("button_1")
elif button is self.button_2:
print("button_2")
elif button is self.button_3:
print("button_3")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
2.1 functools.partial function
import sys
from PyQt5 import QtCore, QtWidgets
from functools import partial
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.button_1 = QtWidgets.QPushButton("button 1")
self.button_1.clicked.connect(partial(self.foo, self.button_1))
self.button_2 = QtWidgets.QPushButton("button 2")
self.button_2.clicked.connect(partial(self.foo, self.button_2))
self.button_3 = QtWidgets.QPushButton("button 3")
self.button_3.clicked.connect(partial(self.foo, self.button_3))
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.button_1)
lay.addWidget(self.button_2)
lay.addWidget(self.button_3)
def foo(self, button):
if button is self.button_1:
print("button_1")
elif button is self.button_2:
print("button_2")
elif button is self.button_3:
print("button_3")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
В моем случае я предпочитаю использовать отправителя, если я могу его использовать,затем functools.partial и, наконец, лямбда-методы