【问题标题】:PyQt5 one signal and multiple slotsPyQt5 一信号多槽
【发布时间】:2016-07-17 15:43:28
【问题描述】:

我在下面提出了一个简单的信号/槽机制。当通过 QSlider::valueChanged() 更改值时,QSlider 会调用该信号。并且插槽是通过 QLCDNumber::display() 方法调用的。

令我困惑的是为什么 PyQt5 的文档如此之少,而大多数文档都指向 Qt5 的链接。我对代码的具体问题是:

1) 如果QSlider::valueChanged() (signal) 需要一个整数作为参数,为什么我们只传入 QLCDNumber::display() (slot) 这是一个 void 函数。因此不会传入任何内容。

2) 在下面注释掉的代码中,我无法调用第二个插槽。您可以为 1 个信号调用的插槽数量是否有限制?如果有我该如何在 PyQt5 中调用多个插槽。

编辑:我相信因为 printLabel() 不是定义的插槽,这就是我遇到问题的原因。我可以在 ::connect() 参数中包含任意数量的插槽吗?或者我是不是在用一种老套的方式来解决这个问题。

import sys
from PyQt5.QtCore import (Qt)
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,
    QVBoxLayout, QApplication)


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def printLabel(self, str):
        print(str)

    def initUI(self):

        lcd = QLCDNumber(self)
        sld = QSlider(Qt.Horizontal, self)

        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)

        #This line works
        sld.valueChanged.connect(lcd.display)

        #This line does not work
        #sld.valueChanged.connect(lcd.display, self.printLabel("hi"))

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Signal & slot')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

【问题讨论】:

  • QWidget 中没有定义像printLabel 这样的槽。您究竟想通过第二个广告位实现什么目标?
  • "您可以为 1 个信号调用的插槽数量是否有限制?" => 没有

标签: qt pyqt pyqt5 qt-signals


【解决方案1】:

按顺序计算你的分数:

  • Qt5 文档包含您需要知道的至少 90% 的内容,因此在 PyQt5 文档中重复所有内容没有什么意义,它主要集中在 PyQt 特有的功能上(请参阅@@例如 987654321@ 文章)。 Qt5 是一个 C++ 库。您无需了解 C++ 即可使用 PyQt(或阅读 Qt 的优秀文档),但您几乎不能指望完全避免它。

  • QSlider.valueChanged 信号向与其连接的所有插槽发送一个 int 值。 QLCDNUmber.display 插槽 接收 字符串、int 或 float 对象(即它具有三个重载)。对于内置的 Qt 插槽,必须有一个与信号发送的内容相匹配的重载。但是 PyQt 中用户定义的槽可以是 any python 可调用对象,签名不匹配也没关系(任何额外的参数都会被丢弃)。话虽如此,可以使用pyqtSlot装饰器为用户定义的槽定义显式签名(因此允许在PyQt中指定多个重载)。

  • 正如上面提到的 PyQt 文章的第一部分所述,信号和插槽都可以有多个连接。文章还详细介绍了 PyQt 特定的 API(包括 pyqtSlot),并举例说明了如何使用它们。

以下是如何连接到您的示例的多个插槽:

class Example(QWidget):    
    ...

    def initUI(self):
        ...

        #connect to a built-in slot
        sld.valueChanged.connect(lcd.display)

        #connect to a user-defined lot
        sld.valueChanged.connect(self.printLabel)

        #any python callable will do
        sld.valueChanged.connect(lambda x: print('lambda:', x))

        ...            

    def printLabel(self, value):
        print('printLabel:', value)

【讨论】:

  • 我看到 QSlider.valueChanged 如何发送一个 int 值。但仅凭文档我不会想到这一点。 QSlider.valueChanged 接受的 int 参数和所有其他信号的参数是插槽正在接收的值吗?
  • @Max.信号的签名描述了它在触发时发送的参数,而不是它在连接时接收到的参数。在 Qt 文档中,信号被定义为函数,因为想要连接到它们的插槽必须在其签名中完全匹配
猜你喜欢
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 2019-04-20
  • 2016-07-27
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
相关资源
最近更新 更多