PyQt5一个信号和多个插槽

Max*_*Max 0 qt pyqt qt-signals pyqt5

我在下面提出了一个简单的信号/插槽机制.当通过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_())
Run Code Online (Sandbox Code Playgroud)

ekh*_*oro 5

按顺序分数:

  • Qt5文档包含至少90%的需要知道的内容,因此在PyQt5文档中重复所有内容并没有什么意义,而PyQt5文档主要集中在PyQt特有的功能上(例如,请参阅信号和插槽文章) ).Qt5是一个C++库.你不需要知道C++就可以使用PyQt(或者阅读Qt优秀的文档),但是你很难完全避免使用它.

  • 所述QSlider.valueChanged信号发送 int值到所有连接到它的时隙.所述QLCDNUmber.display狭槽接收一个字符串,整数或浮点数的对象(即,它具有三个重载).对于内置Qt插槽,必须存在与信号发送匹配的过载.但是PyQt中的用户定义的插槽可以是任何 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)
Run Code Online (Sandbox Code Playgroud)