097.补充_自定义信号_自动连接信号与槽

在这里插入图片描述

我 的 个 人 主 页: 失心疯的个人主页
入 门 教 程 推 荐 : Python零基础入门教程合集
虚 拟 环 境 搭 建 : Python项目虚拟环境(超详细讲解)
PyQt5 系 列 教 程: Python GUI(PyQt5)文章合集
Oracle数据库教程: Oracle数据库文章合集
优 质 资 源 下 载 : 资源下载合集

在这里插入图片描述

自定义信号 自动连接信号与槽

  • 当我们用Designer工具制作完UI界面之后,转换成py文件,在py文件中都会有一句代码

    QtCore.QMetaObject.connectSlotsByName(obj)
    
  • 代码解析:将obj对象内部的子孙对象的信号,按照objectName连接到相关的槽函数

  • 如何通过objectName连接到相关的槽函数呢?

  • 那么就要通过@pyqtSlot()装饰器和特定格式名称的槽函数来实现

  • 对于overload型信号,应该使用@pyqtSlot(type)修饰符声明参数类型,否则会同时发射所有类型参数的信号

  • (解释:overload型信号:信号名称相同,但参数个数或者类型不同的信号)
    例如

  • QPushButton类

    clicked()
    clicked(bool)
    
  • SpinBox类

    valueChanged(int)
    valueChanged(str)
    
  • QDoubleSpinBox类

    valueChanged(float)
    valueChanged(str)
    
  • 语法

    [@pyqtSlot(*types)]
    def on_objectName_信号(val):
        pass
    
    说明
    types:发射信号时所传递数据的类型
    val:用于接收要传递的数据
    
  • 等同于

    obj.objectName.信号[*types].connect(obj.objectName_信号):
    
    def objectName_信号(obj, val):
        pass
    
  • 示例1:普通型信号自动连接

    from PyQt5.Qt import *
    import sys
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('普通信号_自动连接信号与槽')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            btn = QPushButton('测试按钮', self)
            btn.setObjectName('btn')
            btn.resize(100, 50)
            btn.move(100, 100)
    
            QMetaObject.connectSlotsByName(self)
    
        # 特定格式名称的槽函数实现自动连接
        def on_btn_pressed(self):
            print('普通信号自动连接, pressed信号')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    
  • 示例2:自动连接overload型信号,需要通过@pyqtSlot指定参数类型

    from PyQt5.Qt import *
    import sys
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('overload型信号_自动连接')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            labe_total = QLabel('数量:', self)
            labe_price = QLabel('单价:', self)
            labe_amount = QLabel('自动计算金额:', self)
            spb_total = QSpinBox(self)
            spb_total.setObjectName('spb_total')
            spb_price = QSpinBox(self)
            spb_price.setObjectName('spb_price')
            spb_amount = QSpinBox(self)
            spb_amount.setObjectName('spb_amount')
    
            self.spb_total = spb_total
            self.spb_price = spb_price
            self.spb_amount = spb_amount
    
            labe_total.resize(50, 30)
            labe_total.move(10, 100)
            spb_total.resize(180, 30)
            spb_total.move(60, 100)
    
            labe_price.resize(50, 30)
            labe_price.move(260, 100)
            spb_price.resize(180, 30)
            spb_price.move(310, 100)
    
            labe_amount.resize(100, 30)
            labe_amount.move(10, 140)
            spb_amount.resize(370, 30)
            spb_amount.move(120, 140)
    
            QMetaObject.connectSlotsByName(self)
    
        @pyqtSlot(int)
        def on_spb_total_valueChanged(self, total):
            price = self.spb_price.value()
            self.spb_amount.setValue(total * price)
    
        @pyqtSlot(str)
        def on_spb_total_valueChanged(self, total):
            print(f'输入的数量是:{total}')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    
  • 要通过objectName自动连接槽函数注意事项

    • 1、子控件必须通过setobjectName()设置控件名称,Designer工具添加的控件会自动设置objectName
    • 2、必须在所有子控件创建之后执行 QtCore.QMetaObject.connectSlotsByName(obj) 这一句代码
    • 3、* 对于overload型信号,应该使用@pyqtSlot(type)修饰符声明参数类型,否则会同时发射所有类型参数的信号
    • 4、@pyqtSlot()装饰的槽函数必须是obj对象的函数
  • 实例

  • 普通的信号与槽连接方式

    from PyQt5.Qt import *
    import sys
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('普通信号_自动连接信号与槽')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            btn = QPushButton('测试按钮', self)
            btn.setObjectName('btn')
            btn.resize(100, 50)
            btn.move(100, 100)
    
            QMetaObject.connectSlotsByName(self)
    
        def on_btn_pressed(self):
            print('普通信号自动连接, pressed信号')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    
  • overload型信号通过装饰器自动连接信号与槽

    from PyQt5.Qt import *
    import sys
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('装饰器自动连接信号与槽_数据传递')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
        def add_widget(self):
            btn = QPushButton('测试按钮', self)
            btn.setObjectName('btn')
            btn.resize(100, 50)
            btn.move(100, 100)
    
            QMetaObject.connectSlotsByName(self)
    
        @pyqtSlot()
        def on_btn_clicked(self):
            print('装饰器连接:按钮被点击了!')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    
  • overload型信号通过装饰器自动连接信号与槽并传递数据

    from PyQt5.Qt import *
    import sys
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('装饰器自动连接信号与槽_数据传递')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
        def add_widget(self):
            btn = QPushButton('测试按钮', self)
            btn.setObjectName('btn')
            btn.resize(100, 50)
            btn.move(100, 100)
    
            QMetaObject.connectSlotsByName(self)
    
        @pyqtSlot(bool)
        def on_btn_clicked(self, v):
            print('装饰器连接:按钮被点击了!', v)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    
  • 自定义信号 & 自动连接信号与槽

    from PyQt5.Qt import *
    import sys
    
    
    class MyBtn(QPushButton):
        # 定义信号
        rightClicked = pyqtSignal([str], [int], [int, str])
    
        def mousePressEvent(self, evt) -> None:
            super(MyBtn, self).mousePressEvent(evt)
            if evt.button() == Qt.RightButton:
                # 发射信号,并传递数据
                self.rightClicked[str].emit('按钮被点击了')
                self.rightClicked[int].emit(88)
                self.rightClicked[int, str].emit(88, '按钮被点击了')
    
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('自定义信号&装饰器自动连接槽函数')
            self.resize(500, 300)
            self.widget_list()
    
        def widget_list(self):
            btn = MyBtn('测试按钮', self)
            btn.setObjectName('btn1')
    
            # 设置sel对象下所有子孙对象都通过名称连接槽函数
            QMetaObject.connectSlotsByName(self)
    
        @pyqtSlot(int, str)
        def on_btn1_rightClicked(self, v1, v2):
            print(v1, v2)
    
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Windows()
    
        window.show()
        sys.exit(app.exec_())
    

你可能感兴趣的:(PyQt5,python,pyqt,pyqt5,python,gui)