浅谈pyqt5中信号与槽的认识


Posted in Python onFebruary 17, 2019

一、介绍

信号(Signal)和槽(Slot)是Qt中的核心机制,也是PyQt变成中对象之间进行通信的机制

在pyqt5中,每一个QObject对象和pyqt中所有继承自QWidget的控件都支持信号和槽

当信号发射时,连接槽函数将会自动执行,pyqt5中信号与槽通过connect()函数连接起来的。

在pyqt5中信号主要分两类:

1.内置信号(详细参考各个组件)
2.自定义信号(主要用于组件之间数据的传递与窗口交互)

二、内置信号的简单介绍

使用connect()方法将信号与槽函数绑定在一起,使用disconnect()函数将信号与槽解除绑定

1、按钮点击事件(举例)

import sys
from PyQt5.Qt import *


class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('按钮事件')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.init_ui()

  def init_ui(self):
    self.btn.resize(100, 30)
    self.btn.move(100, 50)

    self.btn.clicked.connect(self.btn_hand)

  def btn_hand(self):
    print('按钮点击了')


if __name__ == "__main__":
  app = QApplication(sys.argv)
  window = Window()
  window.show()
  sys.exit(app.exec_())

2、如果连接的事件要传递参数直接使用lambda函数

...
def init_ui(self):
  self.btn.resize(100, 30)
  self.btn.move(100, 50)

  self.btn.clicked.connect(lambda: self.btn_hand(1))

def btn_hand(self, flag):
  print('按钮点击了:{}'.format(flag))
...

三、自定义信号

1、最基本无参数的信号与槽

import sys
from PyQt5.Qt import *


class SignalObj(QObject):
  """
  定义一个信号的类
  """
  # 自定义一个信号
  sendMsg = pyqtSignal()

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

  def run(self):
    self.sendMsg.emit()


class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('自定义事件')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.send = SignalObj()
    # 将事件与槽建立关联
    self.send.sendMsg.connect(self.slot_hand)
    self.init_ui()

  def init_ui(self):
    # 系统中自带的事件与槽函数建立连接
    self.btn.clicked.connect(self.btn_hand)

  def btn_hand(self):
    self.send.run()

  @staticmethod
  def slot_hand():
    print('我是自定义的槽函数')


if __name__ == "__main__":
  app = QApplication(sys.argv)
  window = Window()
  window.show()
  sys.exit(app.exec_())

2、信号中发射出数据

import sys
from PyQt5.Qt import *


class SignalObj(QObject):
  """
  定义一个信号的类
  """
  # 自定义一个信号,注意这个地方定义约束发送出去的参数类型,下面要一致
  sendMsg = pyqtSignal(str)

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

  def run(self):
    self.sendMsg.emit('hello')


class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('自定义事件')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.send = SignalObj()
    # 将事件与槽建立关联
    self.send.sendMsg.connect(self.slot_hand)
    self.init_ui()

  def init_ui(self):
    # 系统中自带的事件与槽函数建立连接
    self.btn.clicked.connect(self.btn_hand)

  def btn_hand(self):
    self.send.run()

  @staticmethod
  def slot_hand(msg):
    print(f'我是自定义的槽函数:{msg}')


if __name__ == "__main__":
  app = QApplication(sys.argv)
  window = Window()
  window.show()
  sys.exit(app.exec_())

3、对于发送多种不同数据类型的事件

import sys
from PyQt5.Qt import *


class SignalObj(QObject):
  """
  定义一个信号的类
  """
  # 自定义一个信号,注意这个地方定义约束发送出去的参数类型,下面要一致
  sendMsg = pyqtSignal([str], [int])

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

  def run(self):
    self.sendMsg[str].emit('hello')
    self.sendMsg[int].emit(999)


class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('自定义事件')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.send = SignalObj()
    # 将事件与槽建立关联(这个地方你要接收那个数据类型的事件)
    self.send.sendMsg[int].connect(self.slot_hand)
    self.init_ui()

  def init_ui(self):
    # 系统中自带的事件与槽函数建立连接
    self.btn.clicked.connect(self.btn_hand)

  def btn_hand(self):
    self.send.run()

  @staticmethod
  def slot_hand(msg):
    print(f'我是自定义的槽函数:{msg}')


if __name__ == "__main__":
  app = QApplication(sys.argv)
  window = Window()
  window.show()
  sys.exit(app.exec_())

四、使用装饰器信号与槽

1、使用格式

@PyQt5.QtCore.pyqtSlot(参数)
def on_发送者对象名称_发射信号名称(self,参数):
 pass

2、注意点,使用装饰器必须定义两个东西

QMetaObject.connectSlotsByName(self)

给需要绑定事件的定义一个id(self.btn.setObjectName('名称'))

3、按钮的普通事件

...
class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('装饰器信号与槽')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.init_ui()

  def init_ui(self):
    self.btn.clicked.connect(self.btn_hand)
    
  @staticmethod
  def btn_hand():
    print('使用connect点击了按钮')
...

4、使用装饰器后的事件

...
class Window(QWidget):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.setWindowTitle('装饰器信号与槽')
    self.resize(500, 500)
    self.move(400, 200)
    self.btn = QPushButton('按钮', self)
    self.init_ui()
    # 要在加载组件后使用
    QMetaObject.connectSlotsByName(self)

  def init_ui(self):
  # 这个地方定义的名字直接在下面使用
    self.btn.setObjectName('btn')

  @pyqtSlot()
  def on_btn_clicked(self):
    print('使用装饰器点击了按钮')
...

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 实现插入排序算法
Jun 05 Python
Python深入学习之对象的属性
Aug 31 Python
Python中类的继承代码实例
Oct 28 Python
Python检测生僻字的实现方法
Oct 23 Python
详解使用pymysql在python中对mysql的增删改查操作(综合)
Jan 18 Python
python中nan与inf转为特定数字方法示例
May 11 Python
Python中元组,列表,字典的区别
May 21 Python
​如何愉快地迁移到 Python 3
Apr 28 Python
python-视频分帧&多帧合成视频实例
Dec 10 Python
Python如何在DataFrame增加数值
Feb 14 Python
python + selenium 刷B站播放量的实例代码
Jun 12 Python
2021年的Python 时间轴和即将推出的功能详解
Jul 27 Python
Laravel+Dingo/Api 自定义响应的实现
Feb 17 #Python
详解pandas库pd.read_excel操作读取excel文件参数整理与实例
Feb 17 #Python
Python线程之定位与销毁的实现
Feb 17 #Python
Pandas读取并修改excel的示例代码
Feb 17 #Python
Python实现去除列表中重复元素的方法总结【7种方法】
Feb 16 #Python
Python字符串逆序输出的实例讲解
Feb 16 #Python
强悍的Python读取大文件的解决方案
Feb 16 #Python
You might like
PHP分页显示制作详细讲解
2006/12/05 PHP
使用php 获取时间今天明天昨天时间戳的详解
2013/06/20 PHP
使用php测试硬盘写入速度示例
2014/01/27 PHP
php使用curl和正则表达式抓取网页数据示例
2014/04/13 PHP
php使用mkdir创建多级目录入门例子
2014/05/10 PHP
Laravel框架数据库CURD操作、连贯操作总结
2014/09/03 PHP
PHP页面实现定时跳转的方法
2014/10/31 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
PHP+redis实现微博的拉模型案例详解
2019/07/10 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
Javascript----文件操作
2007/01/18 Javascript
突发奇想的一个jquery插件
2010/11/19 Javascript
将nodejs打包工具整合到鼠标右键的方法
2013/05/11 NodeJs
jQuery学习笔记之基础中的基础
2015/01/19 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
vue2.0结合DataTable插件实现表格动态刷新的方法详解
2017/03/17 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
node.js中express模块创建服务器和http模块客户端发请求
2019/03/06 Javascript
微信小程序如何实现五星评价功能
2019/10/15 Javascript
python使用response.read()接收json数据的实例
2018/12/19 Python
Python OpenCV调用摄像头检测人脸并截图
2020/08/20 Python
Python程序暂停的正常处理方法
2019/11/07 Python
Python numpy线性代数用法实例解析
2019/11/15 Python
Python中的四种交换数值的方法解析
2019/11/18 Python
解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
2020/07/14 Python
利用CSS3的特性改变文本选中时的颜色
2013/09/11 HTML / CSS
css3弹性盒模型(Flexbox)详细介绍
2014/10/08 HTML / CSS
HTML5之SVG 2D入门8—文档结构及相关元素总结
2013/01/30 HTML / CSS
英国时尚配饰、珠宝和服装网站:KJ Beckett
2020/01/23 全球购物
银行会计业务的个人自我评价
2013/11/02 职场文书
日语求职信范文
2013/12/17 职场文书
十佳班主任事迹材料
2014/01/18 职场文书
批评与自我批评范文
2014/10/15 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
国王的演讲观后感
2015/06/03 职场文书
诚信高考倡议书
2019/06/24 职场文书