I have a QPushbutton
:
btn = QPushButton("Click me")
btn.clicked.connect(lambda: print("one"))
Later in my program, I want to rebind its click handler, I tried to achieve this by calling connect
again:
btn.clicked.connect(lambda: print("two"))
I expected to see that the console only prints two
, but actually it printed both one
and two
. In other words, I actually bound two click handlers to the button.
How can I rebind the click handler?
CodePudding user response:
Signals and slots in Qt are observer pattern (pub-sub) implementation, many objects can subscribe to same signal and subscribe many times. And they can unsubscribe with disconnect
function.
from PyQt5 import QtWidgets, QtCore
if __name__ == "__main__":
app = QtWidgets.QApplication([])
def handler1():
print("one")
def handler2():
print("two")
button = QtWidgets.QPushButton("test")
button.clicked.connect(handler1)
button.show()
def change_handler():
print("change_handler")
button.clicked.disconnect(handler1)
button.clicked.connect(handler2)
QtCore.QTimer.singleShot(2000, change_handler)
app.exec()
In case of lambda you can only disconnect all subscribers at once with disconnect()
(without arguments), which is fine for button case.