1. 程式人生 > >PyQt5 事件與訊號處理

PyQt5 事件與訊號處理

GUI應用程式是事件驅動的。 事件主要由應用程式的使用者生成。 但它們也可以通過其他手段產生,例如:網路連線,視窗管理器或定時器。 當我們呼叫應用程式的exec_()方法時,應用程式進入主迴圈。 主迴圈獲取事件並將其傳送到物件。
在事件模型中,有三個參與者:

  1. 事件來源: 事件源是其狀態更改的物件。 它會生成事件。
  2. 事件物件: 事件物件(event)將狀態更改封裝在事件源中。
  3. 事件目標: 事件目標是要通知的物件。

事件源物件將處理事件的任務委託給事件目標。PyQt5具有獨特的訊號和插槽機制來處理事件。 訊號和槽用於物件之間的通訊。 發生特定事件時發出訊號。 槽可以是任何Python可呼叫的函式

。 當發射連線的訊號時會呼叫一個槽。

栗子1

"""
我們展示了一個QtGui.QLCDNumber和一個QtGui.QDial這個兩個小部件,當我們撥動QDial這個小部件的時候,LCD螢幕就會顯示出此時Dial小部件的值。
"""
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QDial, QApplication)

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUi()

    def
initUi(self):
lcd = QLCDNumber(self) dial = QDial(self) self.setGeometry(300, 300, 350, 250) self.setWindowTitle('早點畢業吧') lcd.setGeometry(100,50,150,60) dial.setGeometry(120,120,100,100) """ 這裡我們將QDial這個小部件的一個valueChanged訊號連線到lcd數字的顯示槽。 QDial物件傳送訊號。 QLCDNumber接收訊號的。 槽是對訊號作出反應的方法。 當然你把上面的QDial小部件換成QSlider,也是一樣的效果。 """
dial.valueChanged.connect(lcd.display) self.show() if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())

栗子2

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QApplication, QLabel)


    def __init__(self):
        super().__init__()
        self.initUi()

    def initUi(self):
        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('早點畢業吧')

        self.lab = QLabel('方向',self)
        self.lab.setGeometry(150,100,50,50)

        self.show()
"""
我們重新實現了keyPressEvent()事件處理程式。當我們按住上、下、左、右方向鍵的時候,視窗中依次會出現對應方位。
"""
    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Up:
            self.lab.setText('↑')
        elif e.key() == Qt.Key_Down:
            self.lab.setText('↓')
        elif e.key() == Qt.Key_Left:
            self.lab.setText('←')
        else:
            self.lab.setText('→')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

栗子3

"""
在這個例子中我們實現了滑鼠座標(x,y)的獲取,以及繪製一條線,這條線的起點座標在(0,0),另外一個端點隨滑鼠移動而移動,同時我們還要計算滑鼠座標與中心點的距離(運用勾股定理進行計算)
"""
#coding=utf-8
import sys
from PyQt5.QtWidgets import (QApplication, QLabel, QWidget)
from PyQt5.QtGui import QPainter

class Example(QWidget):

    distance_from_center = 0

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(200, 200, 1000, 500)
        self.setWindowTitle('早點畢業吧')
        self.label = QLabel(self)
        self.label.resize(500, 40)
        self.show()
        self.pos = None

    def mouseMoveEvent(self, event):
        distance_from_center = round(((event.y() - 250)**2 + (event.x() - 500)**2)**0.5)
        self.label.setText('座標: ( x: %d ,y: %d )' % (event.x(), event.y()) + " 離中心點距離: " + str(distance_from_center))       
        self.pos = event.pos()
        self.update()

    def paintEvent(self, event):
        if self.pos:
            q = QPainter(self)
            q.drawLine(0, 0, self.pos.x(), self.pos.y())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

栗子4

import sys
from PyQt5.QtWidgets import (QApplication, QMessageBox, QWidget, QPushButton)
from random import randint

class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(200, 200, 300, 300)
        self.setWindowTitle('早點畢業吧')

        bt1 = QPushButton('剪刀',self)
        bt1.setGeometry(30,180,50,50)

        bt2 = QPushButton('石頭',self)
        bt2.setGeometry(100,180,50,50)

        bt3 = QPushButton('布',self)
        bt3.setGeometry(170,180,50,50)

        bt1.clicked.connect(self.buttonclicked)
        bt2.clicked.connect(self.buttonclicked)
        bt3.clicked.connect(self.buttonclicked)

        self.show()

    def buttonclicked(self):
        computer = randint(1,3)
"""
        呼叫sender()方法來確定訊號源,根據訊號源確定玩家究竟選擇了石頭、剪刀、布                   中的哪一個。 從而與電腦隨機給出的數字進行比較,判斷輸贏。
"""
        sender = self.sender()

        if sender.text() == '剪刀':
            player = 1
        elif sender.text() == '石頭':
            player = 2
        else:
            player = 3

        if player == computer:
            QMessageBox.about(self, '結果', '平手')
        elif player == 1 and computer == 2:
            QMessageBox.about(self, '結果', '電腦:石頭,電腦贏了!')
        elif player == 2 and computer == 3:
            QMessageBox.about(self, '結果', '電腦:布,電腦贏了!')
        elif player == 3 and computer == 1:
            QMessageBox.about(self,'結果','電腦:剪刀,電腦贏了!')
        elif computer == 1 and player == 2:
            QMessageBox.about(self,'結果','電腦:剪刀,玩家贏了!')
        elif computer == 2 and player == 3:
            QMessageBox.about(self,'結果','電腦:石頭,玩家贏了!')
        elif computer == 3 and player == 1:
            QMessageBox.about(self,'結果','電腦:布,玩家贏了!')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

大栗子

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QMessageBox)
from PyQt5.QtCore import (pyqtSignal, QObject)

class Signal(QObject):
    showmouse = pyqtSignal()#使用pyqtSignal()作為外部Signal類的類屬性建立一個訊號。
'''
建立一個名為showmouse的新訊號。 該訊號在滑鼠按壓事件期間發出。 該訊號連線到QMainWindow的about()的槽
'''
class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(200, 200, 300, 300)
        self.setWindowTitle('早點畢業吧')

        self.s = Signal()
        self.s.showmouse.connect(self.about)#自定義showmouse訊號連線到QMainWindow的about()的槽。

        self.show()

    def about(self):
        QMessageBox.about(self,'滑鼠','你點滑鼠了吧!')

    def mousePressEvent(self, e):
        self.s.showmouse.emit()#當我們用滑鼠指標點選視窗時,會發出showmouse訊號,呼叫相應的槽函式。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())