博客
关于我
pyqt5教程6:信号和事件
阅读量:796 次
发布时间: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/

    你可能感兴趣的文章
    PyTorch Lightning:通过分布式训练扩展深度学习工作流
    查看>>
    PyQt5 - QThread:在线程仍在运行时被销毁
    查看>>
    PyQt5 - 如何从工作线程发出信号以通过 GUI 线程调用事件
    查看>>
    PyQt5 Designer 不工作:此应用程序无法启动,因为无法初始化 Qt 平台插件
    查看>>
    PyQt5 QLCNumber 没有更新
    查看>>
    PyQt5 TabWidget选项卡BarClicked TypeError:本机Qt信号不可调用
    查看>>
    PyQt5 从 PyQt4 转换信号代码
    查看>>
    PyQt5 和 asyncio:从永不完成的收益
    查看>>
    PyQt5 和 Django:如何使用 HTTP 请求(Multipart-form)上传图像?
    查看>>
    PyQt5 按钮运行功能和更新 LCD
    查看>>
    pyqt5 获取Qlabel中的图片并对其进行处理(包括Qimage转换为Mat)
    查看>>
    pyqt5 设置控件在最上层或者在下层
    查看>>
    pyqt5 设置网格布局的间距
    查看>>
    pyTorch Hub 系列#4:PGAN — GAN 模型
    查看>>
    PyQt5-基本窗口控件-QMainWindow
    查看>>
    PyQt5:如何安装/运行 Qt 设计器
    查看>>
    PyQt5——pyqtgraph绘图大招
    查看>>
    PyQt5——多窗口之间数据处理
    查看>>
    PyQt5——多线程、信号与槽
    查看>>
    PyQt5——开发地图软件
    查看>>