编程语言
首页 > 编程语言> > python – PyQt正确使用emit()和pyqtSignal()

python – PyQt正确使用emit()和pyqtSignal()

作者:互联网

我正在阅读有关PyQt5的一些文档,以提出一个简单的信号槽机制.由于设计考虑,我已经停止了.

请考虑以下代码:

import sys
from PyQt5.QtCore import (Qt, pyqtSignal)
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 logLabel(self, str):
        '''log to a file'''
        pass

    def initUI(self):

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

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

        self.setLayout(vbox)

        #redundant connections
        sld.valueChanged.connect(lcd.display)
        sld.valueChanged.connect(self.printLabel)
        sld.valueChanged.connect(self.logLabel)

        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_())

要跟踪对滑块所做的更改,我只需打印并记录所做的更改.我不喜欢的代码是我需要调用sld.valueChanged插槽三次将相同的信息发送到3个不同的插槽.

是否可以创建我自己的pyqtSignal,它将整数发送到单个槽函数.反过来,插槽功能会发出需要进行的更改吗?

>也许我不完全理解emit()的目的,因为在PyQt Signal-Slot docs中没有很好的例子.我们给出的是一个如何实现没有参数的emit的例子.

我想要做的是创建一个处理emit函数的函数.考虑以下:

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


class Example(QWidget):

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

        #create signal
        self.val_Changed = pyqtSignal(int, name='valChanged')

        self.initUI()

    def initUI(self):

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

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

        self.setLayout(vbox)

        sld.val_Changed.connect(self.handle_LCD)
        self.val_Changed.emit()

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

    def handle_LCD(self, text):
        '''log'''
        print(text)
        '''connect val_Changed to lcd.display'''

if __name__ == '__main__':

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

这里显然存在一些严重的设计缺陷.我无法绕过函数调用的顺序.我没有正确实现pyqtSignal.但我确实认为正确陈述以下3点将有助于我制作一个合适的应用程序:

>对于预定义信号:将信号发送到插槽功能.可以重新实现插槽以使用信号值.
>使用一些参数生成pyqtSignal对象.目前尚不清楚这些参数的用途是什么以及它们与“发射”参数的区别.
> emit可以重新实现以将特定信号值发送到槽功能.目前还不清楚为什么我需要从先前存在的信号方法发送不同的值.

随意完全改变我想要做的代码,因为我还没弄清楚它是否在好的风格领域.

解决方法:

您可以定义自己的插槽(任何python可调用)并将其连接到信号,然后从该插槽调用其他插槽.

class Example(QWidget):

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

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

    def logLabel(self, str):
        '''log to a file'''
        pass

    @QtCore.pyqtSlot(int)
    def on_sld_valueChanged(self, value):
        self.lcd.display(value)
        self.printLabel(value)
        self.logLabel(value)

    def initUI(self):

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

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

        self.setLayout(vbox)
        self.sld.valueChanged.connect(self.on_sld_valueChanged)


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

此外,如果要定义自己的信号,则必须将它们定义为类变量

class Example(QWidget):
    my_signal = pyqtSignal(int)

pyqtSignal的参数定义了将在该信号上发出的对象类型,所以在这种情况下,你可以做

self.my_signal.emit(1)

emit can be reimplemented to send specific signal values to the slot
function. It is also not yet clear why I would need to send different
values from previously existing signal methods.

您通常不应该发出内置信号.您应该只需要发出您定义的信号.定义信号时,您可以定义不同类型的不同签名,插槽可以选择要连接的签名.例如,你可以这样做

my_signal = pyqtSignal([int], [str])

这将定义具有两个不同签名的信号,并且插槽可以连接到任一个

@pyqtSlot(int)
def on_my_signal_int(self, value):
    assert isinstance(value, int)

@pyqtSlot(str)
def on_my_signal_str(self, value):
    assert isinstance(value, str)

在实践中,我很少超载信号签名.我通常会创建两个具有不同签名的独立信号,而不是重载相同的信号.但它存在并且在PyQt中受支持,因为Qt具有以这种方式过载的信号(例如,QComboBox.currentIndexChanged)

标签:pyqt5,python,pyqt,signals,signals-slots
来源: https://codeday.me/bug/20190930/1834977.html