PyQt4入門學習筆記(四)

在PyQt4中的事件和信號


事件

全部的GUI應用都是事件驅動的。事件主要是來自於應用的使用者,可是像互聯網鏈接,窗口管理器或者計時器也能夠產生事件。當咱們調用應用的exec_()方法時,應用就進入了主循環。主循環將抓取事件而且將其發送到對應的對象中去。python

在事件模型中,有三個參與者:web

  1. 事件源
  2. 事件對象
  3. 事件目標

事件源是改變狀態的對象。它生成事件。事件對象囊括了在事件源中狀態的改變狀況。事件目標是將要通知的對象,事件源經過事件來操控事件對象。api

PyQ4有獨一無二的信號和槽機制去處理事件。信號和槽被用於在兩個對象間進行交流的。。當特定的事件發生時,信號被髮出。一個槽能夠被任何對象調用。當信號發出並鏈接到槽時,槽被調用。app


新的API

PyQt4.5有一種新式的API用來處理信號和槽。ide

QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), self.onClicked)

這是舊式的APIui

下面是新式的APIthis

button.clicked.connect(self.onClicked)

信號和槽

下面是一個使用信號和槽的簡單示範例子code

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode PyQt4 tutorial 

In this example, we connect a signal
of a QtGui.QSlider to a slot 
of a QtGui.QLCDNumber. 

author: Jan Bodnar
website: zetcode.com 
last edited: October 2011
"""

import sys
from PyQt4 import QtGui, QtCore


class Example(QtGui.QWidget):
    
    def __init__(self):
        super(Example, self).__init__()
        
        self.initUI()
        
    def initUI(self):
        
        lcd = QtGui.QLCDNumber(self)
        sld = QtGui.QSlider(QtCore.Qt.Horizontal, self)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)
        sld.valueChanged.connect(lcd.display)
        
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Signal & slot')
        self.show()
        
def main():
    
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

運行後以下圖
image1對象

在這個例子中,咱們展現了QtGui.QLCDNumberQtGui.QSlider,咱們經過滑動小塊來改變lcd的值blog

sld.valueChanged.connect(lcd.display)

在這裏咱們鏈接了一個滑塊的valueChanged信號到lcddisplay槽。

"sender"是一個發送信號的對象。"receiver"是接受信號的對象。"slot"是對信號起反應的方法。


事件重載管理者(Reimplementing event handler)

在PyQt4裏的事件經常是被事件重載管理者進行過加工的。

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode PyQt4 tutorial 

In this example, we reimplement an 
event handler. 

author: Jan Bodnar
website: zetcode.com 
last edited: October 2011
"""

import sys
from PyQt4 import QtGui, QtCore


class Example(QtGui.QWidget):
    
    def __init__(self):
        super(Example, self).__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() == QtCore.Qt.Key_Escape:
            self.close()
        
def main():
    
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在咱們的例子裏,咱們對keyPressEvent()進行了重載。

def keyPressEvent(self, e):
    
    if e.key() == QtCore.Qt.Key_Escape:
        self.close()

當咱們按下「ESC」時,咱們的應用會被關閉。


事件發送器

有些時候咱們須要知道是哪一個控件發送了信號。基於此,PyQt4有sender()方法

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode PyQt4 tutorial 

In this example, we determine the event sender
object.

author: Jan Bodnar
website: zetcode.com 
last edited: October 2011
"""

import sys
from PyQt4 import QtGui, QtCore


class Example(QtGui.QMainWindow):
    
    def __init__(self):
        super(Example, self).__init__()
        
        self.initUI()
        
    def initUI(self):      

        btn1 = QtGui.QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QtGui.QPushButton("Button 2", self)
        btn2.move(150, 50)
      
        btn1.clicked.connect(self.buttonClicked)            
        btn2.clicked.connect(self.buttonClicked)
        
        self.statusBar()
        
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()
        
    def buttonClicked(self):
      
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' was pressed')
        
def main():
    
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在咱們的例子裏,咱們有兩個按鈕。在buttonClicked()方法裏咱們經過調用senter()方法來肯定是哪一個按鈕被按下了。

btn1.clicked.connect(self.buttonClicked)            
btn2.clicked.connect(self.buttonClicked)

兩個按鈕被鏈接到了相同的槽

def buttonClicked(self):
  
    sender = self.sender()
    self.statusBar().showMessage(sender.text() + ' was pressed')

咱們經過調用senter()方法肯定了信號源。在這個應用的狀態欄,咱們顯示了是哪一個按鈕被按下。

如圖

image2


產生信號

經過QtCore.QObject建立的對象能夠產生信號。在下面的例子裏咱們將看到如何產生特定的信號

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode PyQt4 tutorial 

In this example, we show how to emit a
signal. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt4 import QtGui, QtCore


class Communicate(QtCore.QObject):
    
    closeApp = QtCore.pyqtSignal() 
    

class Example(QtGui.QMainWindow):
    
    def __init__(self):
        super(Example, self).__init__()
        
        self.initUI()
        
        
    def initUI(self):      

        self.c = Communicate()
        self.c.closeApp.connect(self.close)       
        
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Emit signal')
        self.show()
        
        
    def mousePressEvent(self, event):
        
        self.c.closeApp.emit()
        
        
def main():
    
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

咱們建立了一個叫closeApp的信號。當有鼠標點擊事件發生的時候信號觸發。信號鏈接到了QtGui.QMainWindowclose()槽。

class Communicate(QtCore.QObject):
    
    closeApp = QtCore.pyqtSignal()

當咱們點擊窗口時,closeApp信號被觸發,應用關閉。

在這部分,咱們講了信號和槽。

相關文章
相關標籤/搜索