3

Suppose the slot takes an argument, e.g.,

    self._nam = QtNetwork.QNetworkAccessManager(self)
    # ...
    response = self._nam.get(request)
    self.timer.timeout.connect(lambda: self.on_reply_finished(response))

How could the signal be disconnected from the slot? The following gives an error Failed to disconnect signal timeout().:

    self.timer.timeout.disconnect(lambda: self.on_reply_finished(response))

Is it because the lambda isn't a 'real' slot but a Python trick? In that case, how could the response argument be passed to the slot (without making response a member)?

Thanks

Kar
  • 6,063
  • 7
  • 53
  • 82

2 Answers2

4

No, it's because the two lambdas are not the same object.

You need to pass the same reference to the disconnect method you used in the connect method. If you use an anonymous lambda function, there is no way to disconnect it other then calling disconnect() (whithout arguments) on the signal, but that will disconnect all connected signals.

mata
  • 67,110
  • 10
  • 163
  • 162
2

Only if you pass same lambda:

self._on_timeout = lambda: self.on_reply_finished(response)
self.timer.timeout.connect(self._on_timeout)
# ...
self.timer.timeout.disconnect(self._on_timeout)

You may like to append function to timer:

self.timer.on_timeout = lambda: self.on_reply_finished(response)
self.timer.timeout.connect(self.timer.on_timeout)
# ...
self.timer.timeout.disconnect(self.timer.on_timeout)

By the way, you can use functools.partial instead of lambda.

Community
  • 1
  • 1
Mikhail Gerasimov
  • 36,989
  • 16
  • 116
  • 159
  • Please elaborate what would be the benefit of using functools.partial over lambda, in particular if it will prevent signal slot memory leaks as is the case with lambda? – Rhdr Jul 10 '20 at 09:46
  • 1
    @Rhdr it won't prevent memory leak, it can be useful for [other reasons](https://stackoverflow.com/a/3252425/1113207). – Mikhail Gerasimov Jul 10 '20 at 11:12