本文共 5058 字,大约阅读时间需要 16 分钟。
PyQt5 的事件处理与信号机制是应用程序的核心部分,理解这些机制能帮助开发者更好地构建用户界面和管理应用程序的流程。本文将从事件的基本概念、PyQt5 的信号与槽机制、事件处理程序实现以及事件对象的使用等方面进行详细阐述。
PyQt5 应用程序是事件驱动的,事件主要由用户操作或其他系统事件(如计时器、网络连接等)触发。应用程序通过 exec_ 方法进入主循环,主循环负责获取和处理事件。每个事件都是一个对象,具有起点(事件源)和终点(事件目标),通过事件源生成并传递给目标。
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 中,事件通常通过重定义事件处理程序来处理。以下是一个实现自定义事件处理的示例:
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() 事件对象是一个包含丰富信息的 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 提供了 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 允许自定义信号的发射。以下是一个示例,展示如何发射和接收自定义信号:
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/