浅谈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实现爬虫统计学校BBS男女比例(一)
Dec 31 Python
Python的collections模块中namedtuple结构使用示例
Jul 07 Python
python traceback捕获并打印异常的方法
Aug 31 Python
Python数据抓取爬虫代理防封IP方法
Dec 23 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
Feb 08 Python
python仿抖音表白神器
Apr 08 Python
使用Python将字符串转换为格式化的日期时间字符串
Sep 01 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
Jun 29 Python
Python 没有main函数的原因
Jul 10 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
python输入中文的实例方法
Sep 14 Python
python3 sqlite3限制条件查询的操作
Apr 07 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 Zip压缩 在线对文件进行压缩的函数
2010/05/26 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
2013/10/26 PHP
非常全面的php日期时间运算汇总
2015/11/04 PHP
PHP使用XMLWriter读写xml文件操作详解
2018/07/31 PHP
phpStudy vscode 搭建debug调试的教程详解
2020/07/28 PHP
记录几个javascript有关的小细节
2007/04/02 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
Javascript vue.js表格分页,ajax异步加载数据
2016/10/24 Javascript
JS实现“隐藏与显示”功能(多种方法)
2016/11/24 Javascript
用jQuery实现圆点图片轮播效果
2017/03/19 Javascript
十个免费的web前端开发工具详细整理
2017/09/18 Javascript
vue+webpack模拟后台数据的示例代码
2018/07/26 Javascript
用Vue编写抽象组件的方法
2019/05/06 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
javascript实现fetch请求返回的统一拦截
2019/12/22 Javascript
Python单链表的简单实现方法
2014/09/23 Python
全面理解Python中self的用法
2016/06/04 Python
Python设计实现的计算器功能完整实例
2017/08/18 Python
Django获取该数据的上一条和下一条方法
2019/08/12 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
2019/08/30 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
Django模板标签中url使用详解(url跳转到指定页面)
2020/03/19 Python
详解Anaconda安装tensorflow报错问题解决方法
2020/11/01 Python
Ubuntu16安装Python3.9的实现步骤
2020/12/15 Python
python3 kubernetes api的使用示例
2021/01/12 Python
纽约手袋品牌:KARA
2018/03/18 全球购物
美国最大的无人机经销商:DroneNerds
2018/03/20 全球购物
彪马俄罗斯官网:PUMA俄罗斯
2019/07/13 全球购物
Shopping happy life西班牙:以最优惠的价格提供最好的时尚配饰
2020/03/13 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
中学教师实习自我鉴定
2013/09/28 职场文书
《藏戏》教学反思
2014/02/11 职场文书
买卖车协议书
2014/04/21 职场文书
总经理助理岗位职责范本
2015/03/31 职场文书
html5实现点击弹出图片功能
2021/07/16 HTML / CSS
Win10服务主机占用内存怎么办?Win10服务主机进程占用大量内存解决方法
2022/09/23 数码科技