pyqt5教程6:信号和事件
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:信号和事件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 射影几何笔记4:证明的思路
- 下一篇: halcon知识:hough变换检出图像