PyQt5信号-槽机制

signal -> emit -> slot

signal.connect(slot)

signal.disconnect(slot)

信号 (singal) 可以连接无数多个槽 (slot),或者没有连接槽也没有问题,信号也可以连接其他的信号。

连接的基本语句形式如下: who.singal.connect(slot)

信号是 QObject 的一个属性。只有通过 connect方法连接起来,信号-槽机制就建立起来了。类似的信号还有 disconnect 方法和emit 方法。

disconnect 就是断开信号-槽机制,而 emit 就是激活信号。

信号都是类的一个属性,新的信号必须继承自 QObject,然后由 PyQt5.QtCore.pyqtSingal(在 pyqt4 下是 PyQt4.QtCore.pyqtSingal)方法创建,这个方法接受的参数中最重要的是 types 类型,比如 int, bool 之类的,你可以认为这是信号传递的参数类型,但实际传递这些参数值的是 emit 方法。然后槽实际上就是经过特殊封装的函数,这些函数当然需要接受一些参数或者不接受参数,而这些参数具体的值传进来的是由 emit 方法执行的,然后我们通过 who.singal.connect(slot) 这样的形式将某个信号和某个槽连接起来, who 的信号,然后信号类自带的连接方法,然后连接到 slot 某个函数上,在这里隐藏的一个重要细节就是 emit 方法,比如说你定义一个新的信号,需要将点击屏幕的具体 x,y 坐标发送出去,内置的信号-槽将这一机制都完成了,如果你自己定义的信号和槽的话,比如 pyqtSingal(int,int) ,发送给 func(x,y),具体 x 和 y 的值你需要通过 emit(x,y) 来发送。至于什么时候发送,已经发送的 x,y 值的获取,这应该又是另外一个信号-槽机制的细节。

1. 自定义信号

from PyQt5.QtCore import *
from PyQt5.QtGui import *

class FindDialog(QDialog):
    findNext = pyqtSignal(str, Qt.CaseSensitivity)
    findPrevious = pyqtSignal(str, Qt.CaseSensitivity)

2. 自定义槽

class FindDialog(QDialog):
    ......
    @pyqtSlot()
    def findClicked(self):
        text = self.lineEdit.text()
        if self.caseCheckBox.isChecked():
            cs = Qt.CaseSensitive
        else:
            cs = Qt.CaseInsensitive
        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)

3. 发射信号

class FindDialog(QDialog):
    ......

    @pyqtSlot()
    def findClicked(self):
        ......
        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)

4. 以下是完整的示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
‘‘‘
    查找对话框示例, 自定义信号槽
‘‘‘

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class FindDialog(QDialog):
    findNext = pyqtSignal(str, Qt.CaseSensitivity)
    findPrevious = pyqtSignal(str, Qt.CaseSensitivity)

    def __init__(self, parent = None):
        super().__init__(parent)
        label = QLabel(self.tr(‘Find &what:‘))
        self.lineEdit = QLineEdit()
        label.setBuddy(self.lineEdit)
        self.caseCheckBox = QCheckBox(self.tr(‘Match &case‘))
        self.backwardCheckBox = QCheckBox(self.tr(‘Search &backward‘))
        self.findButton = QPushButton(self.tr(‘&Find‘))
        self.findButton.setDefault(True)
        self.findButton.setEnabled(False)
        closeButton = QPushButton(self.tr(‘Close‘))
        self.lineEdit.textChanged.connect(self.enableFindButton)
        self.findButton.clicked.connect(self.findClicked)
        closeButton.clicked.connect(self.close)
        topLeftLayout = QHBoxLayout()
        topLeftLayout.addWidget(label)
        topLeftLayout.addWidget(self.lineEdit)
        leftLayout = QVBoxLayout()
        leftLayout.addLayout(topLeftLayout)
        leftLayout.addWidget(self.caseCheckBox)
        leftLayout.addWidget(self.backwardCheckBox)
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.findButton)
        rightLayout.addWidget(closeButton)
        rightLayout.addStretch()
        mainLayout = QHBoxLayout()
        mainLayout.addLayout(leftLayout)
        mainLayout.addLayout(rightLayout)
        self.setLayout(mainLayout)
        self.setWindowTitle(self.tr(‘Find‘))
        self.setFixedHeight(self.sizeHint().height())

    def enableFindButton(self, text):
        self.findButton.setEnabled(bool(text))

    @pyqtSlot()
    def findClicked(self):
        text = self.lineEdit.text()
        if self.caseCheckBox.isChecked():
            cs = Qt.CaseSensitive
        else:
            cs = Qt.CaseInsensitive
        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)

if __name__ ==  ‘__main__‘:
    import sys
    app = QApplication(sys.argv)
    findDialog = FindDialog()

    def find(text, cs):
        print(‘find:‘, text, ‘cs‘, cs)

    def findp(text, cs):
        print(‘findp:‘, text, ‘cs‘, cs)

    findDialog.findNext.connect(find)
    findDialog.findPrevious.connect(findp)
    findDialog.show()
    sys.exit(app.exec_())    

d

时间: 2024-10-25 16:31:32

PyQt5信号-槽机制的相关文章

PyQt5快速入门(二)PyQt5信号槽机制

PyQt5快速入门(二)PyQt5信号槽机制 一.信号槽机制简介 1.信号槽简介 信号槽是Qt的核心机制,也是PyQt编程中对象进行通信的机制.在Qt中,QObject对象和PyQt中所有继承自QWidget的控件都支持信号槽机制.当信号发射时,连接的槽函数会自动执行.在PyQt5中,信号与槽函数通过object.signal.connect()方法进行连接.信号槽特点如下:(1)一个信号可以连接多个槽(2)一个信号可以连接另一个信号(3)信号参数可以是任意Python类型(4)一个槽可以监听多

从零开始实现信号槽机制:一

我们从一个具体的问题入手: "现在有一堆按钮,以及一堆电器,按钮对它需要控制的对象一无所知,电器也不知道它们开关的具体类型,它们之间的关系可能是一对多,也可能是多对一,并且需要支持动态添加和删除,应该如何设计这个结构?" 这里有个形象的图: 为了实现组件间的控制,我们很容易想到"回调函数",对于C++开发者,我们肯定不希望一个类自身的处理函数存在于类外,但是类成员函数中被自动添加的隐形this形参造成了函数指针调用的不匹配,于是我们想到了使用static成员函数:

深入理解信号槽机制(一)(大局观,讲的不错)

这篇文章来自于 A Deeper Look at Signals and Slots,Scott Collins 2005.12.19.需要说明的是,我们这里所说的“信号槽”不仅仅是指 Qt 库里面的信号槽,而是站在一个全局的高度,从系统的角度来理解信号槽.所以在这篇文章中,Qt 信号槽仅仅作为一种实现来介绍,我们还将介绍另外一种信号槽的实现——boost::signal.因此,当你在文章中看到一些信号的名字时,或许仅仅是为了描述方便而杜撰的,实际并没有这个信号. 什么是信号槽? 这个问题我们可

Qt开发之信号槽机制

一.信号槽机制原理 1.如何声明信号槽 Qt头文件中一段的简化版: class Example: public QObject { Q_OBJECT signals: void customSignal(); void customSignal(int i) public slots: void customSlot(); void customSlot(int i); }; 2.宏与MOC源对象 摘录代码: // qobjectdefs.h i. … ii. #define slots iii

Qt高级——Qt信号槽机制源码解析

Qt高级--Qt信号槽机制源码解析 基于Qt4.8.6版本 一.信号槽机制的原理 1.信号槽简介 信号槽是观察者模式的一种实现,特性如下:A.一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知:B.一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候--也可以说是信号发出的时候--被调用的函数:C.信号与槽的连接,形成一种观察者-被观察者的关系:D.当事件或者状态发生改变的时候,信号就会被发出:同时,信号发出者有义务调用所有注册的对这个事件(信号)感兴趣的函数(槽).信号和

非Qt工程使用Qt的信号槽机制

非Qt工程,使用Qt的信号槽机制,蛋疼不?反正我现在就是要做这样一件蛋疼的事. 要使用Qt的信号槽机制,下面是从Qt Assist里面关于 signal & slots 的一句介绍: All classes that contain signals or slots must mention Q_OBJECT at the top of their declaration. They must also derive (directly or indirectly) from QObject.

[转]深入理解信号槽机制

原文不可考 来源链接http://blog.csdn.net/liuuze5/article/details/53523463 深入理解信号槽(一) 这篇文章来自于 A Deeper Look at Signals and Slots,Scott Collins 2005.12.19.需要说明的是,我们这里所说的"信号槽"不仅仅是指 Qt 库里面的信号槽,而是站在一个全局的高度,从系统的角度来理解信号槽.所以在这篇文章中,Qt 信号槽仅仅作为一种实现来介绍,我们还将介绍另外一种信号槽的

Qt信号槽机制源码解析

Qt信号槽机制源码解析 来源 https://blog.51cto.com/9291927/2070398 一.信号槽机制的原理 1.信号槽简介 信号槽是观察者模式的一种实现,特性如下:A.一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知:B.一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候——也可以说是信号发出的时候——被调用的函数:C.信号与槽的连接,形成一种观察者-被观察者的关系:D.当事件或者状态发生改变的时候,信号就会被发出:同时,信号发出者有义务调用所有注

信号槽机制的心得

使用信号和槽机制,要注意以下问题: 1.信号和槽的机制是非常有效的,但是它不像“真正的”回调那样快.信号和槽稍微有些慢,这是因为它们所提供的灵活性.但这种损失相对来说是比较小的.但要追求高效率的话,比如在实时系统中就要尽量少用这种机制. 2.信号和槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时有可能形成死循环,所以,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样的信号. 3.如果一个信号和多个槽相关联的话,那当这个信号被发射时,与之相关联的槽的执行顺序将