PyQt 小部件 connect() 和 disconnect()

Posted

技术标签:

【中文标题】PyQt 小部件 connect() 和 disconnect()【英文标题】:PyQt Widget connect() and disconnect() 【发布时间】:2014-03-02 10:31:27 【问题描述】:

根据条件,我想将按钮连接/重新连接到不同的功能。

假设我有一个按钮:

myButton = QtGui.QPushButton()

对于这个例子,假设我检查是否有互联网连接。

if connected == True:
    myButton.clicked.connect(function_A)

elif connected == False:
    myButton.clicked.connect(function_B)

首先,我想在按钮被重新分配/重新连接到另一个功能(function_A 或 function_B)之前断开一个按钮与它已经连接的任何功能。 其次,我已经注意到,在重新连接按钮后,需要额外单击按钮才能使用新功能。在按钮重新连接到另一个功能后,它仍会尝试运行以前的功能 - 按钮之前连接到的功能(重新连接之前)。请指教。提前致谢!

稍后编辑:

似乎小部件的 .disconnect() 方法可用于断开按钮与其连接的功能的连接。

myButton.disconnect()

不幸的是,如果小部件未连接到任何功能,.disconnect() 会引发错误。 为了解决这个问题,我使用了 Try/Except。但我宁愿使用更优雅的解决方案...

try: myButton.clicked.disconnect() 
except Exception: pass

【问题讨论】:

引发了什么异常?有点怪。请注意,myButton.disconnect() 与 myButton.clicked.disconnect() 不同,您实际上指的是哪个? @Schollii。它引发了TypeError。这个例外一点也不奇怪:事实上,这是非常可取的。之所以引入它,是因为老式的连接和断开信号的方法会默默地失败,这可以隐藏很多潜在的错误。简而言之,以更 Pythonic 的方式引发异常。 感谢您的解释。我只是不明白为什么应该断开所有信号的函数应该将“当前没有连接”视为异常行为。 OTOH,如果您尝试断开连接(someSignal)并且该信号不存在,那么我可以将其视为应标记的异常情况。但是无论如何,它既不在这里也不在那里,谢谢您的信息。 【参考方案1】:

如果您需要在许多地方重新连接信号,那么您可以定义一个通用的实用函数,如下所示:

def reconnect(signal, newhandler=None, oldhandler=None):        
    try:
        if oldhandler is not None:
            while True:
                signal.disconnect(oldhandler)
        else:
            signal.disconnect()
    except TypeError:
        pass
    if newhandler is not None:
        signal.connect(newhandler)

...

if connected:
    reconnect(myButton.clicked, function_A)
else:
    reconnect(myButton.clicked, function_B)

(注意:安全断开特定处理程序需要循环,因为它可能已连接多次,而disconnect(slot) 一次只删除一个连接。)。

【讨论】:

所以如果你做signal.disconnect() - 没有提供slot 参数 - 那么这个信号将与它的所有插槽断开连接?换句话说 - 在这种情况下不需要循环? @K.Mulier 那是what the docs say,所以如果你看到不同的行为,那将是一个错误。通过检查sender.receivers(sender.signal) 的输出很容易对此进行测试。【参考方案2】:

试试这个:

from PyQt4 import QtGui as gui

app = gui.QApplication([])

myButton = gui.QPushButton()

def function_A():
    myButton.clicked.disconnect() #this disconnect all!
    myButton.clicked.connect(function_B)
    print 'function_A'

def function_B():
    myButton.clicked.disconnect(function_B) #this disconnect function_B
    myButton.clicked.connect(function_A)
    print 'function_B'

myButton.clicked.connect(function_A)
myButton.setText("Click me!")
myButton.show()

app.exec_()

【讨论】:

您知道如何检查小部件是否连接到功能吗?我发现有 .isSignalConnected() 小部件方法。可惜我不知道怎么用... 嗯,你应该阅读this,我认为没有希望,但如果你找到了方法,请告诉我;)

以上是关于PyQt 小部件 connect() 和 disconnect()的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 制作子类小部件

PyQt4:使用 QPushButton 小部件从 QList 小部件中删除项目

通过 pyqt5 动态添加和删除小部件

Pyqt5 addStretch 在小部件之间?

小部件未在 pyqt5 中显示标签

PyQt:如何在 QStackedWidget 中切换小部件