PyQt5 一信号多槽

问题描述 投票:0回答:1

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

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

1) 如果 QSlider::valueChanged() (信号)需要一个整数作为参数,为什么我们只传入 QLCDNumber::display() (槽),这是一个 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_())
qt pyqt pyqt5 signals-slots
1个回答
9
投票

按顺序排列你的点:

  • Qt5 文档至少包含您需要了解的 90%,因此在 PyQt5 文档中重复所有内容没有什么意义,相反,它主要集中于 PyQt 特有的功能(请参阅信号和槽文章,例如)。 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 slot 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)
    
© www.soinside.com 2019 - 2024. All rights reserved.