• 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

  • 相关阅读:
    大公司?小公司?
    git 学习笔记
    django学习笔记
    web servieces 学习小栗子
    python列表推导式
    什么叫事务,事务的特性
    监听问题汇总
    oracle数据库导入导出
    ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务--解决办法(转)
    目标修正
  • 原文地址:https://www.cnblogs.com/yaoyu126/p/7508763.html
Copyright © 2020-2023  润新知