博客
关于我
pyqt5教程6:信号和事件
阅读量:799 次
发布时间:2023-03-05

本文共 5058 字,大约阅读时间需要 16 分钟。

PyQt5 的事件处理与信号机制是应用程序的核心部分,理解这些机制能帮助开发者更好地构建用户界面和管理应用程序的流程。本文将从事件的基本概念、PyQt5 的信号与槽机制、事件处理程序实现以及事件对象的使用等方面进行详细阐述。

一、PyQt5 的事件模型

PyQt5 应用程序是事件驱动的,事件主要由用户操作或其他系统事件(如计时器、网络连接等)触发。应用程序通过 exec_ 方法进入主循环,主循环负责获取和处理事件。每个事件都是一个对象,具有起点(事件源)和终点(事件目标),通过事件源生成并传递给目标。

PyQt5 的事件模型包括三个关键组成部分:

  • 事件源(Event Source):是触发事件的对象。它的状态发生变化时会生成事件。
  • 事件对象(Event Object):封装了事件源中的状态变化信息。
  • 事件目标(Event Target):接收事件并处理事件的对象。
  • 事件源负责生成事件,事件对象携带事件信息,事件目标则决定如何处理该事件。

    二、PyQt5 的信号与槽机制

    PyQt5 使用信号与槽机制进行对象间通信。信号是特定事件的通知机制,槽是对信号的响应方法。当特定事件发生时,程序会发出信号,信号可以连接到任意可调用的槽。

    以下是一个简单的示例:

    signals_slots.py"""ZetCode PyQt5 tutorialIn this example, we connect a signal of a QSlider to a slot of a QLCDNumber.Author: Jan BodnarWebsite: zetcode.com"""import sysfrom PyQt5.QtCore import Qtfrom 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()

    三、PyQt5 事件处理程序的自定义

    在 PyQt5 中,事件通常通过重定义事件处理程序来处理。以下是一个实现自定义事件处理的示例:

    reimplement_handler.py"""ZetCode PyQt5 tutorialIn this example, we reimplement an event handler.Author: Jan BodnarWebsite: zetcode.com"""import sysfrom PyQt5.QtCore import Qtfrom 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()

    四、PyQt5 事件对象的使用

    事件对象是一个包含丰富信息的 Python 对象,具体信息取决于事件类型。以下是一个示例,展示如何使用事件对象获取鼠标坐标:

    event_object.py"""ZetCode PyQt5 tutorialIn this example, we display the x and y coordinates of a mouse pointer in a label widget.Author: Jan BodnarWebsite: zetcode.com"""import sysfrom PyQt5.QtCore import Qtfrom PyQt5.QtWidgets import (    QWidget, QApplication, QGridLayout, QLabel)class Example(QWidget):    def __init__(self):        super().__init__()        self.initUI()    def initUI(self):        grid = QGridLayout()        x, y = 0, 0        self.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()

    五、PyQt5 事件发送

    在某些情况下,需要确定事件的发送者。PyQt5 提供了 sender 方法来实现这一点。以下是一个示例:

    event_sender.py"""ZetCode PyQt5 tutorialIn this example, we determine the event sender object.Author: Jan BodnarWebsite: zetcode.com"""import sysfrom PyQt5.QtWidgets import (    QMainWindow, QPushButton)from PyQt5.QtCore import Qtclass 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()

    六、PyQt5 发射信号

    PyQt5 允许自定义信号的发射。以下是一个示例,展示如何发射和接收自定义信号:

    custom_signal.py"""ZetCode PyQt5 tutorialIn this example, we show how to emit a custom signal.Author: Jan BodnarWebsite: zetcode.com"""import sysfrom PyQt5.QtCore import pyqtSignal, QObjectfrom 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()

    转载地址:http://bcafk.baihongyu.com/

    你可能感兴趣的文章
    Private Destructor
    查看>>
    private和protected能同时修饰成员变量吗_天天用注解你了解注解是怎么实现的吗?...
    查看>>
    privoxy Invalid header received from client.
    查看>>
    Privoxy代码下载
    查看>>
    Progress Kemp LoadMaster 远程命令执行漏洞复现(CVE-2024-1212)
    查看>>
    Project configuration is not up-to-date with pom.xml. Run Maven->Update Project
    查看>>
    Project Euler 15 Lattice paths
    查看>>
    Project Euler 48 Self powers( 大数求余 )
    查看>>
    Project Euler Problem 12: Highly divisible triangular number
    查看>>
    ProjectEuler 2
    查看>>
    projection介绍及EPSG:4326和EPSG:3857的投射转换
    查看>>
    project打开文件时,显示无法识别此文件格式?
    查看>>
    Prometheus + Grafana on Kubernetes部署
    查看>>
    prometheus + grafana进行服务器资源监控
    查看>>
    Prometheus Grafana 展示平台
    查看>>
    Prometheus pushgateway使用详解
    查看>>
    Prometheus 云原生 - Prometheus 数据模型、Metrics 指标类型、Exporter 相关
    查看>>
    Prometheus 云原生 - 基于 file_sd、http_sd 实现 Service Discovery
    查看>>
    Prometheus 云原生 - 微服务监控报警系统 (Promethus、Grafana、Node_Exporter)部署、简单使用
    查看>>
    Prometheus 介绍
    查看>>