pyqt отключить слоты. Новый стиль

Я назначаю слот с этим.

...
self.query = QtGui.QLineEdit(self)            
self.query.textChanged.connect(lambda: self.makeThread(self.googleSearch()))
self.query.returnPressed.connect(lambda: self.launchNavigator(1))
...

а как отключить? Я пробовал с этим, но он не работает...

self.query.textChanged.disconnect(lambda: self.makeThread(self.googleSearch()))
self.query.returnPressed.disconnect(lambda: self.launchNavigator(1))

person felipe    schedule 24.03.2013    source источник


Ответы (3)


Лямбда-выражения возвращают разные функции, которые (более или менее случайно ;)) будут делать то же самое. Следовательно, то, к чему вы подключили свой сигнал, не совпадает со второй лямбдой, которую вы используете при попытке ее отключить; см. этот пример:

>>> f = lambda x: x
>>> g = lambda x: x
>>> f is g
False

Вы можете либо использовать self.query.textChanged.disconnect() без каких-либо параметров, что отключит сигнал от всех слотов (что может быть нормально, если у вас есть только это одно соединение), либо вам придется где-то хранить ссылку на лямбду:

self.func1 = lambda: self.makeThread(self.googleSearch())
self.query.textChanged.connect(self.func1)
...
self.query.textChanged.disconnect(self.func1)
person rainer    schedule 24.03.2013
comment
То, что вы сказали о ламбах, верно и для functools.partial? - person Guimoute; 24.06.2019

Я хотел бы добавить предостережение/расширение к ответу @rainer, касающемуся связанных методов. Имейте в виду, что привязка метода к экземпляру (например, путем написания self.slotname) фактически создает новое замыкание каждый раз (как в this вопрос).

Следовательно, у вас будет такая же проблема с выполнением

def test_slot(self):
    self.makeThread(self.googleSearch())

...

    self.query.textChanged.connect(self.test_slot)

...

    self.query.textChanged.disconnect(self.test_slot)

как вы сделали с исходным lambda в своем вопросе. Решение состоит в том, чтобы сохранить замыкание self.test_slot в атрибуте, как предлагает @rainer. Это необходимо, потому что новый объект, примерно эквивалентный lambda: type(self).test_slot(self), генерируется каждый раз, когда вы пишете self.test_slot в своем коде. Следующее будет работать нормально, если вы правильно ведете бухгалтерский учет:

    self.func = self.test_slot
    self.query.textChanged.connect(self.func)

...

    self.query.textChanged.disconnect(self.func)
person Mad Physicist    schedule 25.04.2017

Существует элегантный способ отключения сигнала с помощью объекта QConnection, возвращаемого исходным соединением. Так:

self.conn1 = self.query.textChanged.connect(lambda: self.makeThread(self.googleSearch()))
self.conn2 = self.query.returnPressed.connect(lambda: self.launchNavigator(1))

И затем впоследствии:

self.disconnect(self.conn1)
self.disconnect(self.conn2)

Эта функция не была реализована до версии PyQt 5.13.1, хотя в Qt она уже давно существует.

person mkam    schedule 26.10.2019