浅谈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 相关文章推荐
py中的目录与文件判别代码
Jul 16 Python
在Python中操作字符串之replace()方法的使用
May 19 Python
windows上安装Anaconda和python的教程详解
Mar 28 Python
Python实现的计算马氏距离算法示例
Apr 03 Python
Sanic框架Cookies操作示例
Jul 17 Python
Python实例方法、类方法、静态方法的区别与作用详解
Mar 25 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
Dec 13 Python
python 实现从高分辨图像上抠取图像块
Jan 02 Python
详解python 降级到3.6终极解决方案
Feb 06 Python
python+selenium+Chrome options参数的使用
Mar 18 Python
keras实现图像预处理并生成一个generator的案例
Jun 17 Python
PyCharm配置KBEngine快速处理代码提示冲突、配置命令问题
Apr 03 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实现负载均衡的加权轮询方法分析
2018/08/22 PHP
Ubuntu 16.04中Laravel5.4升级到5.6的步骤
2018/12/07 PHP
详解Javascript 装载和执行
2014/11/17 Javascript
jquery $(document).ready()和window.onload的区别浅析
2015/02/04 Javascript
对Web开发中前端框架与前端类库的一些思考
2015/03/27 Javascript
对象转换为原始值的实现方法
2016/06/06 Javascript
javascript日期比较方法实例分析
2016/06/17 Javascript
Javascript数组循环遍历之forEach详解
2016/11/07 Javascript
js获取当前时间(昨天、今天、明天)
2016/11/23 Javascript
微信小程序  checkbox组件详解及简单实例
2017/01/10 Javascript
js实现上传并压缩图片效果
2018/01/10 Javascript
vue渲染时闪烁{{}}的问题及解决方法
2018/03/28 Javascript
JavaScript中.min.js和.js文件的区别讲解
2019/02/13 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
webpack中的模式(mode)使用详解
2020/02/20 Javascript
Python中的数学运算操作符使用进阶
2016/06/20 Python
wxPython的安装图文教程(Windows)
2017/12/28 Python
对Python生成汉字字库文字,以及转换为文字图片的实例详解
2019/01/29 Python
python实现12306登录并保存cookie的方法示例
2019/12/17 Python
python deque模块简单使用代码实例
2020/03/12 Python
详解pandas.DataFrame.plot() 画图函数
2020/06/14 Python
python分布式爬虫中消息队列知识点详解
2020/11/26 Python
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
八年级生物教学反思
2014/01/22 职场文书
高等教育学自荐书范文
2014/02/10 职场文书
蓝颜请假条
2014/04/11 职场文书
给校长的建议书100字
2014/05/16 职场文书
甲午风云观后感
2015/06/02 职场文书
安全教育第一课观后感
2015/06/17 职场文书
详解php中流行的rpc框架
2021/05/29 PHP
Python基础数据类型tuple元组的概念与用法
2021/08/02 Python
CSS布局之浮动(float)和定位(position)属性的区别
2021/09/25 HTML / CSS
Java 在线考试云平台的实现
2021/11/23 Java/Android
JavaScript阻止事件冒泡的方法
2021/12/06 Javascript
Python+DeOldify实现老照片上色功能
2022/06/21 Python
详解SQL报错盲注
2022/07/23 SQL Server