简体   繁体   English

pyqt 断开插槽。 新风格

[英]pyqt disconnect slots. New style

I assign a slot with this.我为此分配了一个插槽。

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

but how can I disconnect?但我怎样才能断开连接? I tried with this but it does not work...我试过这个,但它不起作用......

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

The lambda expressions return different functions that (more or less by chance ;) ) will do the same thing. lambda 表达式返回不同的函数,这些函数(或多或少是偶然的 ;) )会做同样的事情。 Therefore, what you connected your signal to is not the same thing as the second lambda you're using when trying to disconnect it;因此,您将信号连接到的内容与您尝试断开连接时使用的第二个 lambda 不同; see this example:看这个例子:

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

You can either use self.query.textChanged.disconnect() without any parameters, which will disconnect the signal from all slots (which might be ok if you only have that one connection) or you will have to store a reference to the lambda somewhere:您可以使用不带任何参数的self.query.textChanged.disconnect() ,这将断开所有插槽的信号(如果您只有一个连接,这可能没问题),或者您必须在某处存储对 lambda 的引用:

self.func1 = lambda: self.makeThread(self.googleSearch())
self.query.textChanged.connect(self.func1)
...
self.query.textChanged.disconnect(self.func1)

I would like to add a caveat/extension to @rainer's answer pertaining to bound methods.我想在@rainer 的关于绑定方法的答案中添加一个警告/扩展。 Keep in mind that binding a method to an instance (eg, by writing self.slotname ) actually creates a new closure every time (as in this question).请记住,将方法绑定到实例(例如,通过编写self.slotname )实际上每次都会创建一个新的闭包(如问题)。

You would therefore have the same problem doing因此你会遇到同样的问题

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

...

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

...

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

as you did with the original lambda in your question.正如您在问题中对原始lambda所做的那样。 The solution is to store the closure self.test_slot in an attribute, as @rainer suggests.正如@rainer 建议的那样,解决方案是将闭包self.test_slot存储在一个属性中。 This is necessary because a new object that is roughly equivalent to lambda: type(self).test_slot(self) is generated every time you write self.test_slot in your code.这是必要的,因为每次在代码中编写self.test_slot时都会生成一个大致相当于lambda: type(self).test_slot(self)的新对象lambda: type(self).test_slot(self) The following will work fine as long as you do the book-keeping accurately:只要您准确地进行簿记,以下内容就可以正常工作:

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

...

    self.query.textChanged.disconnect(self.func)

There is an elegant way of disconnecting a signal using the QConnection object returned by the original connection.有一种使用原始连接返回的 QConnection 对象断开信号的优雅方法。 So:所以:

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

And then subsequently:然后随后:

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

This feature was not implemented prior to PyQt 5.13.1, although it has existed in Qt for a long time.这个特性在 PyQt 5.13.1 之前没有实现,虽然它在 Qt 中已经存在很长时间了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM