PyQt5 中的事件和信号

在 PyQt5 编程教程的这一部分中,我们探讨了应用程序中发生的事件和信号。这部分比较抽象,也最难记忆。

一、PyQt5的事件

GUI 应用程序是事件驱动的。事件主要由应用程序的用户生成。但它们也可以通过其他方式生成;例如Internet 连接、窗口管理器或计时器。当我们调用应用程序的 exec_ 方法时,应用程序进入主循环。主循环获取事件并将它们发送给对象。

在事件模型中,有三个组成:

  • event source 事件源
  • event object  状态对象
  • event target  要通知的对象

事件源是:状态发生变化的对象。它生成事件。

事件对象(event)封装了事件源中的状态变化。

事件目标是要通知的对象。事件源对象将处理事件的任务委托给事件目标。

PyQt5 有一个独特的信号和槽机制来处理事件。信号和槽用于对象之间的通信。发生特定事件时会发出信号。插槽可以是任何 Python 可调用的。发出连接信号时调用插槽。

二、PyQt5 信号和槽

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

signals_slots.py

#!/usr/bin/python"""
ZetCode PyQt5 tutorialIn this example, we connect a signal
of a QSlider to a slot of a QLCDNumber.Author: Jan Bodnar
Website: zetcode.com
"""import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,QVBoxLayout, QApplication)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('Signal and slot')self.show()def main():app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())if __name__ == '__main__':main()

在我们的示例中,我们显示一个 QtGui.QLCDNumber 和一个 QtGui.QSlider。我们通过拖动滑块旋钮来更改 LCD 编号。

sld.valueChanged.connect(lcd.display)

在这里,我们将滑块的 valueChanged 信号连接到 lcd 数字的显示槽。

发送者是发送信号的对象。接收器是接收信号的对象。插槽是对信号做出反应的方法。

Figure: Signal & slot

三、PyQt5 重新实现事件处理程序

PyQt5 中的事件通常通过重新实现事件处理程序来处理。

reimplement_handler.py

#!/usr/bin/python"""
ZetCode PyQt5 tutorialIn this example, we reimplement an
event handler.Author: Jan Bodnar
Website: zetcode.com
"""import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplicationclass Example(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 250, 150)self.setWindowTitle('Event handler')self.show()def keyPressEvent(self, e):if e.key() == Qt.Key_Escape:self.close()def main():app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())if __name__ == '__main__':main()

在我们的示例中,我们重新实现了 keyPressEvent 事件处理程序。

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

如果我们单击 Escape 按钮,应用程序将终止。

四、PyQt5的事件对象

事件对象是一个 Python 对象,它包含许多描述事件的属性。事件对象特定于生成的事件类型。

event_object.py

#!/usr/bin/python"""
ZetCode PyQt5 tutorialIn this example, we display the x and y
coordinates of a mouse pointer in a label widget.Author: Jan Bodnar
Website: zetcode.com
"""import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabelclass Example(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):grid = QGridLayout()x = 0y = 0self.text = f'x: {x},  y: {y}'self.label = QLabel(self.text, self)grid.addWidget(self.label, 0, 0, Qt.AlignTop)self.setMouseTracking(True)self.setLayout(grid)self.setGeometry(300, 300, 450, 300)self.setWindowTitle('Event object')self.show()def mouseMoveEvent(self, e):x = e.x()y = e.y()text = f'x: {x},  y: {y}'self.label.setText(text)def main():app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())if __name__ == '__main__':main()

In this example, we display the x and y coordinates of a mouse pointer in a label widget.

self.text = f'x: {x},  y: {y}'self.label = QLabel(self.text, self)

x 和 y 坐标显示在 QLabel 小部件中。

self.setMouseTracking(True)

默认情况下禁用鼠标跟踪,因此当鼠标移动时至少按下一个鼠标按钮时,小部件才会接收鼠标移动事件。如果启用了鼠标跟踪,即使没有按下按钮,小部件也会接收鼠标移动事件。

def mouseMoveEvent(self, e):x = e.x()y = e.y()text = f'x: {x},  y: {y}'self.label.setText(text)

e 是事件对象;它包含有关已触发事件的数据;在我们的例子中,鼠标移动事件。使用 x 和 y 方法,我们确定鼠标指针的 x 和 y 坐标。我们构建字符串并将其设置为标签小部件。

正在上传…重新上传取消转存失败重新上传取消

Figure: Event object

五、PyQt5事件发送

有时很方便知道哪个小部件是信号的发送者。为此,PyQt5 有 sender 方法。

event_sender.py

#!/usr/bin/python"""
ZetCode PyQt5 tutorialIn this example, we determine the event sender
object.Author: Jan Bodnar
Website: zetcode.com
"""import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplicationclass Example(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):btn1 = QPushButton("Button 1", self)btn1.move(30, 50)btn2 = QPushButton("Button 2", self)btn2.move(150, 50)btn1.clicked.connect(self.buttonClicked)btn2.clicked.connect(self.buttonClicked)self.statusBar()self.setGeometry(300, 300, 450, 350)self.setWindowTitle('Event sender')self.show()def buttonClicked(self):sender = self.sender()self.statusBar().showMessage(sender.text() + ' was pressed')def main():app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())if __name__ == '__main__':main()

我们的示例中有两个按钮。在 buttonClicked 方法中,我们通过调用 sender 方法来确定我们点击了哪个按钮。

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

Both buttons are connected to the same slot.

def buttonClicked(self):sender = self.sender()self.statusBar().showMessage(sender.text() + ' was pressed')

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

Figure: Event sender

六、PyQt5发射信号

从 QObject 创建的对象可以发出信号。以下示例显示了我们如何发出自定义信号。

custom_signal.py

#!/usr/bin/python"""
ZetCode PyQt5 tutorialIn this example, we show how to
emit a custom signal.Author: Jan Bodnar
Website: zetcode.com
"""import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplicationclass 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, 450, 350)self.setWindowTitle('Emit signal')self.show()def mousePressEvent(self, event):self.c.closeApp.emit()def main():app = QApplication(sys.argv)ex = Example()sys.exit(app.exec_())if __name__ == '__main__':main()
我们创建了一个名为 closeApp 的新信号。此信号在鼠标按下事件期间发出。该信号连接到 QMainWindow 的关闭插槽。
class Communicate(QObject):closeApp = pyqtSignal()
使用 pyqtSignal 作为外部通信类的类属性创建信号。
self.c = Communicate()
self.c.closeApp.connect(self.close)
自定义 closeApp 信号连接到 QMainWindow 的关闭槽。
def mousePressEvent(self, event):self.c.closeApp.emit()

当我们用鼠标指针单击窗口时,会发出 closeApp 信号。应用程序终止。

在 PyQt5 教程的这一部分中,我们介绍了信号和槽。

pyqt5教程6:信号和事件相关推荐

  1. (3)pyqt5教程--->信号与槽初试

    GitHub连接: 本专栏所有源代码的GitHub直通车 上一篇已经讲了如何使用QTdesigner生成ui文件并转化为py文件,最终实现界面代码分离的效果 信号与槽作是 QT 的核心机制,是一种高级 ...

  2. pyqt5 发送键盘信号_Python教程 | Pyqt5实战教程之操作交互处理,原来这么简单!...

    PyQt5用来编写Python脚本的应用界面.本文详细介绍PyQt5教程之操作交互处理,并通过丰富的实战提高文章的可读性.在教程后面会附带PyQt5操作交互处理常见问题. 一.前言: 不管在PyQt还 ...

  3. PyQt5教程(十二)——实现QQ登录界面(六、实现鼠标拖动界面,鼠标事件)

    PyQt5教程(十二)--实现QQ登录界面(五.实现鼠标拖动界面,鼠标事件) 一.实现界面可以随着鼠标进行拖动 1.主要就是对鼠标事件的实现: def mousePressEvent(self, ev ...

  4. pyqt5教程9:Widgets组件

    PyQt5 widgets 小部件是应用程序的基本构建块. PyQt5 有各种各样的小部件,包括按钮.复选框.滑块或列表框.在本教程的这一部分,我们将描述几个有用的小部件:QCheckBox.切换模式 ...

  5. python PyQt5教程

    引用文章1:python PyQt5 教程 参考文章2:PyQt5 python官方教程 Qt for Python pyqt5-基础 PyQt5是一套来自Digia的Qt5应用框架和Python的粘 ...

  6. PyQt5 笔记3 -- 信号与槽

    PyQt5 笔记3 – 信号与槽(signals and slots) 学习资料: PyQt5 教程 PyQt5 官方文档 1.信号与槽 QT所有的应用都是事件驱动的.事件大部分都是由用户的行为产生的 ...

  7. PyQt5教程-04-关闭窗口

    最简单的关闭一个窗口的方法是点击标题栏上的 x 标志.但是,在下面的例子中,我们将展示如何通过编程来控制关闭窗口.我们将使用PyQt5的信号/槽. 以下是我们在例子中使用到的 QPushButton ...

  8. pyqt5教程12:拖放功能

    在 PyQt5 教程的这一部分中,我们将讨论拖放操作. 在计算机图形用户界面中,拖放是单击虚拟对象并将其拖动到不同位置或另一个虚拟对象上的动作(或支持动作).一般来说,它可以用来调用多种动作,或者在两 ...

  9. PyQt5 教程 《日期和时间》

    导读 目录 导读 PyQt5的日期和时间 QDate,QTime,QDateTime 当前日期和时间 UTC时间 天数 天数的差异 日期时间算术 夏令时 Unix时代 Julian day 历史战役 ...

最新文章

  1. rap 接口管理 java_有没有类似阿里rap的api管理方案(rap太卡了)
  2. String insert()总结
  3. linux下jdk源码安装,Linux JDK 源码安装
  4. SM3密码杂凑算法源码解析
  5. linux下阻塞的系统调用,Linux下文件的阻塞与非阻塞对部分系统调用的影响
  6. HDU 4753 Fishhead’s Little Game(DFS)
  7. Pure-Ftp:基于虚拟账号的FTP服务器
  8. map、mapPartitions、mapValues、mapWith、flatMap、flatMapWith、flatMapValues
  9. android 对象输出到文件
  10. 二叉树前序遍历、中序遍历、后序遍历 递归和非递归方式实现
  11. Liferay中页面的权限控制
  12. 互联网寒冬下,为什么就你被裁了?
  13. 网格计算——下一代分布式计算
  14. ANSYS WORKBENCH基础学习之应力奇异及位移结果对比
  15. 数据挖掘—概念空间挖掘FindS算法的C++实现
  16. [imx6 VPU]硬解码+示例[ffmpeg获取海康rtsp h264流 QT显示]
  17. 微信小程序 - 无法获取云端数据库中的数据的问题(修改云端数据库权限)
  18. 拼多多用户优惠券使用行为预测分析项目
  19. Web初学者-作业3-[聚光灯效果]
  20. 线性布局(LinearLayout)

热门文章

  1. Python入门100题 | 第009题
  2. 深度学习100例-卷积神经网络(AlexNet)手把手教学 | 第11天
  3. 在Windows环境下配置QT Creator 读取NC文件(NetCDP,C++接口)
  4. 【LeetCode从零单排】No36 Valid Sudoku
  5. Android系统截屏的实现(附代码)
  6. 【机器学习算法-python实现】采样算法的简单实现
  7. 【ssh从零单排】eclipse和tomcat整合配置
  8. 超有用的,从此vi变得友好了
  9. Active Object 并发模式在 Java 中的应用--转载
  10. command pattern