几个信号可以有一个插槽吗?

时间:2014-06-19 18:10:39

标签: qt pyqt signals pyside

我有几个按钮,每个按钮都有一个信号,只要点击按钮就会发出一个属性(比如一个整数)。在父母班级中,我希望能够抓住任何按钮'根据按钮中的特定属性发出并做出反应。

我可以想办法通过单独连接'来做到这一点。父类中的每个按钮,但这似乎是错误的,并且很麻烦,因为在我的应用程序中,我添加和删除按钮作为功能的一部分。我可能错误地想到了......以及建议?

2 个答案:

答案 0 :(得分:2)

在Qt中,您可以将任何信号连接到任何插槽。这也意味着您可以使用单个插槽将单个信号与多个插槽或多个信号连接。

现在,如果每个按钮都做了不同的事情并且没有那么多,我会手动将每个按钮与另一个插槽连接,只是为了让事情很好地分开。

在您的情况下,您可能希望以自动方式将所有按钮连接到单个插槽,并在此插槽中通过self.sender()确定原始按钮,然后对此信息执行某些操作。

示例:

每当小部件中出现新按钮时

new_button.clicked.connect(self.parent().buttons_clicked)
# always the same recipient

在父类中:

def buttons_clicked(self):
  button = self.sender()
  # do something useful depending on the button that sent the signal

这里缺少的是您转移属性的方式(数字或其他)。您现在没有指定如何执行此操作,但通过连接到同一插槽可能不会显着改变。


编辑:作为旁注,Qt中也有大致相同的事件。 Signals/slots vs events是一个有趣的讨论。根据您的问题(许多动态按钮)而不是连接和断开连接,发送事件可能会更好。

答案 1 :(得分:1)

您可以这样做:

from functools import partial

def buttonEvent(i):
    print(i)

for i in range(5):
    button = QtWidgets.QPushButton("Button: " + str(i))
    button.clicked.connect(partial(buttonEvent, i))

在Qt中,您需要将信号连接到函数名称,不能指定参数或任何东西。当涉及到许多独特的小部件或生成的小部件或诸如此类的东西时,这很烦人。两个不错的解决方案是使用partial和lambda。当我想调用一个独立于变量的参数的函数时(例如button.clicked.connect(lambda: print("Button clicked"))),我使用lambda。如果函数调用依赖于稍后将更改的某个变量,则需要使用partial,这将立即保存变量内容。 Lambda将等到被调用以使用变量(因此,在上述情况下,如果使用lambda,所有按钮都将打印“4”。)