PyQt5每天必学之事件与信号


Posted in Python onApril 20, 2018

这一部分我们将探索 PyQt5 的事件和信号是如何在应用程序中实现的。

Events事件

所有的GUI应用程序都是事件驱动的。应用程序事件主要产生自用户,但它们也可通过其他方法来产生,例如一个互联网连接,一个窗口管理器,或计时器。当我们调用应用程序的exec_()方法,应用程序进入主循环。主循环检测各种事件,并把它们发送到事件对象。

在事件模型中,有三个参与者:

  • event source(事件源)
  • event object(事件对象)
  • event target(事件目标)

事件源是对象的状态改变而产生事件。事件对象(事件)是封装在事件源中状态变化的对象。事件目标是希望被通知的对象。事件源对象代表处理一个事件到事件目标的任务。

PyQt5使用独特的信号和槽机制来处理事件。信号和槽用于对象之间的通信,当一个特定的事件发生时,信号被发射。槽可以是任意的Python调用。信号发射时连接到槽被调用。

Signals & slots信号和槽

这是一个简单的例子演示PyQt5的信号和槽。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 教程

这个例子中,我们将QSlider的滑动信号连接到QLCDNumber中。

作者:我的世界你曾经来过
博客:http://blog.csdn.net/weiaitaowang
最后编辑:2016年8月1日
"""

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QSlider, 
QLCDNumber, QVBoxLayout)
from PyQt5.QtCore import Qt

class Example(QWidget):

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

 self.initUI()

 def initUI(self):

 lcd = QLCDNumber(self)
 sld = QSlider(Qt.Horizontal, self)

 vbox = QVBoxLayout()
 vbox.addWidget(lcd)
 vbox.addWidget(sld)

 self.setLayout(vbox)
 sld.valueChanged.connect(lcd.display)

 self.setGeometry(300, 300, 250, 150)
 self.setWindowTitle('信号/槽') 
 self.show()

if __name__ == '__main__':

 app = QApplication(sys.argv)
 ex = Example()
 sys.exit(app.exec_())

在我们的例子中,将用到QtGui.QLCDNumber和QtGui.QSlider。我们通过拖动滑块改变LCD数字。

sld.valueChanged.connect(lcd.display)

在这里,滑块的 valueChanged 信号连接到 lcd 的显示(display)槽。

发送器是对象发送信号。接收器是接收信号的对象。槽的是反馈给信号的方法。

程序执行后

PyQt5每天必学之事件与信号

覆写系统事件处理程序

事件在PyQt5中的处理往往通过重写事件来处理程序。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 教程

在这个例子中,我们执行事件处理程序。

作者:我的世界你曾经来过
博客:http://blog.csdn.net/weiaitaowang
最后编辑:2016年8月1日
"""

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt

class Example(QWidget):

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

 self.initUI()

 def initUI(self):

 self.setGeometry(300, 300, 250, 150)
 self.setWindowTitle('事件处理') 
 self.show()

 def keyPressEvent(self, e):
 if e.key() == Qt.Key_Escape:
  self.close()

if __name__ == '__main__':

 app = QApplication(sys.argv)
 ex = Example()
 sys.exit(app.exec_())

在我们的例子中,我们重新实现 keyPressEvent() 事件处理程序。

def keyPressEvent(self, e):
 if e.key() == Qt.Key_Escape:
 self.close()

如果我们按下键盘上的 Esc 键,应用程序终止。

Event sender事件发送

为了方便区分多个连接到同一事件目标的事件源,在PyQt5中可以使用sender()方法。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 教程

在这个例子中,我们确定事件发送对象。

作者:我的世界你曾经来过
博客:http://blog.csdn.net/weiaitaowang
最后编辑:2016年8月1日
"""

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton

class Example(QMainWindow):

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

 self.initUI()

 def initUI(self):

 btn1 = QPushButton('按钮一', self)
 btn1.move(30, 50)

 btn2 = QPushButton('按钮二', self)
 btn2.move(150, 50)

 btn1.clicked.connect(self.buttonClicked)
 btn2.clicked.connect(self.buttonClicked)

 self.statusBar()

 self.setGeometry(300, 300, 300, 150)
 self.setWindowTitle('事件发送') 
 self.show()

 def buttonClicked(self):

 sender = self.sender()
 self.statusBar().showMessage(sender.text() + ' 被按下')

if __name__ == '__main__':

 app = QApplication(sys.argv)
 ex = Example()
 sys.exit(app.exec_())

在我们的例子中有两个按钮。两个按钮都连接 buttonClicked() 方法,我们通过调用 sender() 方法响应单击的按钮。

btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked)

两个按钮连接到同一个槽。

def buttonClicked(self):

 sender = self.sender()
 self.statusBar().showMessage(sender.text() + ' 被按下')

我们通过调用 sender() 方法确定信号源。在应用程序的状态栏,显示被按下按钮的标签。

程序执行后

PyQt5每天必学之事件与信号

定制发射信号

从一个QObject 创建的对象可以发出信号。在下面的例子中,我们将看看我们如何能够定制发出信号。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 教程

在这个例子中,我们显示了如何以发射信号。

作者:我的世界你曾经来过
博客:http://blog.csdn.net/weiaitaowang
最后编辑:2016年8月1日
"""

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtSignal, QObject

class Communicate(QObject):
 closeApp = pyqtSignal()

class Example(QMainWindow):

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

 self.initUI()

 def initUI(self):

 self.c = Communicate()
 self.c.closeApp.connect(self.close)

 self.setGeometry(300, 300, 300, 150)
 self.setWindowTitle('发射信号') 
 self.show()

 def mousePressEvent(self, event):

 self.c.closeApp.emit()

if __name__ == '__main__':

 app = QApplication(sys.argv)
 ex = Example()
 sys.exit(app.exec_())

我们创建一个名为closeApp新的信号。这个信号是发射按下鼠标事件。该信号被连接到QMainWindow中的close()槽。

class Communicate(QObject):
 closeApp = pyqtSignal()

创建继承自 QObject 的 Communicate 类,该类中有一个 pyqtSignal() 类的属性。

self.c = Communicate()
self.c.closeApp.connect(self.close)

将我们自定义的 closeApp 信号连接到QMainWindow中的close()槽。

def mousePressEvent(self, event):
 self.c.closeApp.emit()

当我们鼠标在程序窗口出现点击动作时,closeApp信号被发射(emit)。应用程序终止。

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

Python 相关文章推荐
详解Python中break语句的用法
May 14 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
Python实现的自定义多线程多进程类示例
Mar 23 Python
Python爬虫包BeautifulSoup异常处理(二)
Jun 17 Python
用python代码将tiff图片存储到jpg的方法
Dec 04 Python
对python实现二维函数高次拟合的示例详解
Dec 29 Python
Python设计模式之观察者模式原理与用法详解
Jan 16 Python
python flask安装和命令详解
Apr 02 Python
python爬取本站电子书信息并入库的实现代码
Jan 20 Python
Python逐行读取文件内容的方法总结
Feb 14 Python
sqlalchemy实现时间列自动更新教程
Sep 02 Python
python全栈开发语法总结
Nov 22 Python
pandas groupby 分组取每组的前几行记录方法
Apr 20 #Python
基于pandas数据样本行列选取的方法
Apr 20 #Python
pandas实现选取特定索引的行
Apr 20 #Python
PyQT实现多窗口切换
Apr 20 #Python
使用实现pandas读取csv文件指定的前几行
Apr 20 #Python
浅析python打包工具distutils、setuptools
Apr 20 #Python
PyQt5每天必学之切换按钮
Aug 20 #Python
You might like
常用星际术语索引(新手指南)
2020/03/04 星际争霸
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
php中的curl_multi系列函数使用例子
2014/07/29 PHP
PHP页面转UTF-8中文编码乱码的解决办法
2015/10/20 PHP
php array_walk 对数组中的每个元素应用用户自定义函数详解
2016/11/18 PHP
javascript FormatNumber函数实现方法
2008/12/30 Javascript
javascript Array对象基础知识小结
2010/11/16 Javascript
formValidator3.3的ajaxValidator一些异常分析
2011/07/12 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
jQuery简单实现两级下拉菜单效果代码
2015/09/15 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
JavaScript中函数声明与函数表达式的区别详解
2016/08/18 Javascript
Jquery Easyui菜单组件Menu使用详解(15)
2016/12/18 Javascript
Vue实现动态显示textarea剩余字数
2017/05/22 Javascript
JavaScript设置名字输入不合法的实现方法
2017/05/23 Javascript
浅谈使用mpvue开发小程序需要注意和了解的知识点
2018/05/23 Javascript
Vue.js实现的计算器功能完整示例
2018/07/11 Javascript
在AngularJs中设置请求头信息(headers)的方法及不同方法的比较
2018/09/04 Javascript
vue axios基于常见业务场景的二次封装的实现
2018/09/21 Javascript
JS 实现发送短信验证码的“59秒后重新发送验证短信”功能
2019/08/23 Javascript
vue组件命名和props命名代码详解
2019/09/01 Javascript
用jQuery实现抽奖程序
2020/04/12 jQuery
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
在Python的Tornado框架中实现简单的在线代理的教程
2015/05/02 Python
利用Pandas读取文件路径或文件名称包含中文的csv文件方法
2018/07/04 Python
解决python xlrd无法读取excel文件的问题
2018/12/25 Python
Pandas中DataFrame的分组/分割/合并的实现
2019/07/16 Python
Django表单提交后实现获取相同name的不同value值
2020/05/14 Python
python中线程和进程有何区别
2020/06/17 Python
python中HTMLParser模块知识点总结
2021/01/25 Python
python解包概念及实例
2021/02/17 Python
幼师专业毕业生自荐信
2013/09/29 职场文书
太太口服液广告词
2014/03/20 职场文书
党支部三严三实对照检查材料思想汇报
2014/09/29 职场文书
运动会致辞稿
2015/07/29 职场文书
MySQL命令行操作时的编码问题详解
2021/04/14 MySQL