浅谈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遍历类中所有成员的方法
Mar 18 Python
在Python中使用Neo4j数据库的教程
Apr 16 Python
使用Python导出Excel图表以及导出为图片的方法
Nov 07 Python
python设计模式大全
Jun 27 Python
Python实现的简单线性回归算法实例分析
Dec 26 Python
机器学习实战之knn算法pandas
Jun 22 Python
python求加权平均值的实例(附纯python写法)
Aug 22 Python
Python3视频转字符动画的实例代码
Aug 29 Python
使用Python为中秋节绘制一块美味的月饼
Sep 11 Python
Python基于read(size)方法读取超大文件
Mar 12 Python
python实现进度条的多种实现
Apr 29 Python
FP-growth算法发现频繁项集——构建FP树
Jun 24 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
Windows下的PHP5.0安装配制详解
2006/09/05 PHP
php图片验证码代码
2008/03/27 PHP
php提示Call-time pass-by-reference has been deprecated in的解决方法[已测]
2012/05/06 PHP
php操作xml入门之cdata区段
2015/01/23 PHP
PHP使用DOM和simplexml读取xml文档的方法示例
2017/02/08 PHP
Javascript 个人笔记(没有整理,很乱)
2007/07/07 Javascript
jquery 图片轮换效果
2010/07/29 Javascript
基于jQuery的烟花效果(运动相关)点击屏幕出烟花
2012/06/14 Javascript
用js判断页面是否加载完成实现代码
2012/12/11 Javascript
防止浏览器记住用户名及密码的简单实用方法
2013/04/22 Javascript
javaScript 动态访问JSon元素示例代码
2013/08/30 Javascript
jquery中获取id值方法小结
2013/09/22 Javascript
JavaScript中如何通过arguments对象实现对象的重载
2014/05/12 Javascript
freemarker判断对象是否为空的方法
2015/08/13 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
2018/03/02 Javascript
浅谈PDF.js使用心得
2018/06/07 Javascript
node.js学习笔记之koa框架和简单爬虫练习
2018/12/13 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
2019/01/18 Javascript
vue实现搜索过滤效果
2019/05/28 Javascript
vue router 跳转时打开新页面的示例方法
2019/07/28 Javascript
JavaScript函数IIFE使用详解
2019/10/21 Javascript
python字符串编码识别模块chardet简单应用
2015/06/15 Python
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
纽约海:Sea New York
2018/11/04 全球购物
美国家用和厨房电器销售网站:Appliances Connection
2020/01/24 全球购物
美术教师岗位职责
2014/03/18 职场文书
大学生军训自我鉴定范文
2014/09/18 职场文书
四风自我剖析材料思想汇报
2014/10/01 职场文书
2014年党的群众路线活动个人整改措施
2014/10/28 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
《失物招领》教学反思
2016/02/20 职场文书
《女娲补天》读后感5篇
2019/12/31 职场文书
MySQL高级进阶sql语句总结大全
2022/03/16 MySQL