pyqt5学习之自定义信号

记录自定义信号创建和使用

1.信号的定义:在类内部,以类属性形式定义;pyqtSignal([int],[str])

                注意:一个信号连接另外一个信号时,必需保证参数类型和个数一致。

信号的定义需要掌握以下几点:

  1. 信号的声明:  信号名 = pyqtSignal(类型)

  2. 信号的触发:  信号名.emit(信号内容)

  3. 信号的接收:  信号所在类实例.信号名.connect(接收函数)

下文以一个右击按钮信号demo示例

需要自定义某个控件的信号,你需要创建一个新类继承原来的类

from PyQt5.Qt import *

# 自定义信号按键方法程序
class Btn(QPushButton):
    rightClicked = pyqtSignal([str],[int, str])
    #设置自定义信号函数pyqtSignal在使用时默认传递一个参数,可以使用[int, str...]传递多个参数

    def mousePressEvent(self, evt):
        super(Btn, self).mousePressEvent(evt)
        #一定要使用super,因为程序先看子类方法再去看父类方法,子类方法覆盖了
        #父类方法,会到导致mousePressEvent()的其他方法无法使用
        #evt:事件对象
        if evt.button() == Qt.RightButton:
            print('应该发射右击信号')
            self.rightClicked[str].emit(self.text())
            #传递值,默认是pyqtSignal的第一个参数,可以加[str]确定传送目标值
            self.rightClicked[int, str].emit(888,'xuexi')
            # emit:确保自定义信号的发射,保证槽函数正确使用

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle('自定义信号')
        self.resize(500,500)
        self.setup_ui()

    def setup_ui(self):
        btn = Btn('xx',self) # 继承自定信号类
        btn.rightClicked[int, str].connect(lambda content, c2:print("按钮右键被点击了", content, c2))
        btn.pressed.connect(lambda :print("按钮被按下"))



if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()

    sys.exit(app.exec_())

案例二:连接一个槽函数

from PyQt5.Qt import *


# 自定义信号按键方法程序
class Btn(QPushButton):
    rightClicked = pyqtSignal() # 定义一个rightClicked信号

    # 设置自定义信号函数pyqtSignal在使用时默认传递一个参数,可以使用[int, str...]传递多个参数

    def mousePressEvent(self, evt):
        super(Btn, self).mousePressEvent(evt)
        # 一定要使用super,因为程序先看子类方法再去看父类方法,子类方法覆盖了
        # 父类方法,会到导致mousePressEvent()的其他方法无法使用
        # evt:事件对象
        if evt.button() == Qt.RightButton:
            print('应该发射右击信号')
            self.rightClicked.emit() # 触发信号



class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle('自定义信号')
        self.resize(500, 500)
        self.setup_ui()

    def cao(self):
        print('lianjie')

    def setup_ui(self):
        btn = Btn('xx', self)  # 继承自定信号类
        btn.rightClicked.connect(self.cao) # 链接槽函数


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    window = Window()
    window.show()

    sys.exit(app.exec_())

2.利用装饰器自动连接信号与槽

核心函数:QMetaObject.connectSlotsByName(obj);@pyqtSlot()

from PyQt5.Qt import *

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle('装饰器连接信号与槽的学习')
        self.resize(500,500)
        self.setup_ui()

    def setup_ui(self):
        btn = QPushButton('测试按钮',self)
        btn.setObjectName('btn')
        btn.resize(200,200)
        btn.move(100,100)

        btn2 = QPushButton("测试按钮2", self)
        btn2.setObjectName("btn2")
        btn2.resize(200, 200)
        btn2.move(100, 300)

        QMetaObject.connectSlotsByName(self)
        # 注意QMetaObject.connectSlotsByName(obj)一定要放在槽函数控件设置后
        # 否则无法使用该方法

    @pyqtSlot()  # 将@pyqtSlot()放置在槽函数上
    def on_btn_clicked(self):
        print('成功连接')
    # 槽函数格式为on_ObjectName(控件设置的setObjectName)_信号

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)

    window = Window()
    window.show()


    sys.exit(app.exec_())

自定义信号和装饰器连用

from PyQt5.Qt import *


class Btn(QPushButton):
    rightClicked = pyqtSignal()
    #设置自定义信号函数pyqtSignal在使用时默认传递一个参数,可以使用[int, str...]传递多个参数

    def mousePressEvent(self, evt):
        super(Btn, self).mousePressEvent(evt)
        #一定要使用super,因为程序先看子类方法再去看父类方法,子类方法覆盖了
        #父类方法,会到导致mousePressEvent()的其他方法无法使用
        #evt:事件对象
        if evt.button() == Qt.RightButton:
            print('应该发射右击信号')
            #传递值,默认是pyqtSignal的第一个参数,可以加[str]确定传送目标值
            self.rightClicked.emit()
            # emit:信号的发射

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle('装饰器连接信号与槽的学习')
        self.resize(500,500)
        self.setup_ui()

    def setup_ui(self):
        btn = Btn('测试按钮',self)
        btn.setObjectName('btn')
        btn.resize(200,200)
        btn.move(100,100)

        btn2 = QPushButton("测试按钮2", self)
        btn2.setObjectName("btn2")
        btn2.resize(200, 200)
        btn2.move(100, 300)

        QMetaObject.connectSlotsByName(self)
        # 注意QMetaObject.connectSlotsByName(obj)一定要放在槽函数控件设置后
        # 否则无法使用该方法

    @pyqtSlot()  # 将@pyqtSlot()放置在槽函数上
    def on_btn_rightClicked(self):
        print('成功连接')
    # 槽函数格式为on_ObjectName(控件设置的setObjectName)_信号

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)

    window = Window()
    window.show()


    sys.exit(app.exec_())

 上述是通过一个控件类增加自定义信号,下面讨论在一个类方法内使用方法

应用场景比如自动刷新数据

步骤分三步:1.创建信号: 信号名 = pyqtSignal(类型)

            2.建立信号和槽的连接: 信号所在类实例.信号名.connect(self.槽函数名)

            3.发射信号:信号名.emit()

from PyQt5.Qt import *
from PyQt5.QtCore import *
import sys

class Window(QWidget):
    signal = pyqtSignal()  # 1.创建信号

    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle("自定义信号")
        self.resize(500,500)
        self.move(500,500)
        self.setup_ui()

    def setup_ui(self):
        self.text= QLineEdit(self)
        self.text.setText('5')
        self.text.resize(100,100)
        self.text.move(50,50)
        self.signal.connect(self.cao)  # 2.自定义信号连接槽函数;注意自定义信号只能类实例调用
        self.signal.emit() #3.发射信号


    def cao(self):
        self.text.setText('4')

if __name__ =='__main__':

    app = QApplication(sys.argv)

    window = Window()
    window.show()

    sys.exit(app.exec_())

参考:http://www.broadview.com.cn/article/824

原文地址:https://www.cnblogs.com/mosewumo/p/12466309.html