电竞比分网-中国电竞赛事及体育赛事平台

分享

PyQt4 教程(5)

 學海無涯GL 2014-10-24

PyQt4 中的事件與信號

在這一節(jié)中,將會接觸到程序中事件和信號的 we will explore events and singnals occuring in applications.

事件

事件是gui程序中最重要的部分。事件是由用或系統(tǒng)發(fā)出的。當我們調用程序的exec_()方法,程序進入了主循環(huán)。主循環(huán)獲取事件并負責將其傳送到對象。 Trolltech通過其獨特的信號與槽的機制來進行掌控。

事件是gui程序的最重要部分。所有的gui程序是事件驅動的。程序在運行期間,處理各種事件,主要處理由用戶激發(fā)的程序,但也可以由網(wǎng)絡鏈接,窗口管理器,計時器。在事件模型,有三個組成部分:


  • 事件源(event source)
  • 事件對象(event object)
  • 事件目標(event target)

事件源 是發(fā)生狀態(tài)改變改變的對象。它產(chǎn)生事件。事件對象將事件源狀態(tài)變化封裝起來。事件目標是需要告知的對象。事件源對象將事件傳送給事件目標處理。

當我們調用exec_() 方法,程序進入了主循環(huán)。主循環(huán)獲取事件并將它們發(fā)送給對象。信號和槽用來對象間的通信。當一個事件發(fā)生時,信號 就生成了。slot 可以是任何python可調用的函數(shù)。信號所連接的槽的調用,是在信號生成后。

新 API

PyQt4.5 引入信號與槽的一種新的API 風格。

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

上邊是老式的API

button.clicked.connect(self.onClicked)

這是新式的更符合python標準。

信號&槽

這是一個展示PyQt4中的信號與槽。

#!/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()

In our example, we display a QtGui.QLCDNumber and a QtGui.QSlider. We change the lcd number by dragging the slider knob.

sld.valueChanged.connect(lcd.display)

Here we connect a valueChanged signal of the slider to the display slot of the lcd number.

The sender is an object that sends a signal. The receiver is the object, that receives the signal. The slot is the method, that reacts to the signal.


Signals & slot
Figure: Signal & slot

重載事件處理器

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鍵,程序結束。

事件發(fā)送者

有時候需要知道信號的發(fā)送者,為了方便使用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()方法里我們判斷哪個按鈕被按下使用了sender() 。

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

兩個按鈕都被連接到了相同的槽函數(shù)。

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

我們使用sender()方法判斷信號的發(fā)出者。在程序的狀態(tài)欄里顯示哪里個按鈕被按下。


Event sender
Figure: Event sender

發(fā)出信號

從QtCore.QObject 中創(chuàng)建出來的類都能發(fā)出信號。如果我們點擊按鈕,一個 clicked() 信號生成。在下邊例子里我們?nèi)绾紊梢粋€信號。

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

"""
ZetCode PyQt4 tutorial 

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

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

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()

我們創(chuàng)建了一個名叫closeApp的信號。當鼠標按下時,信號發(fā)出。信號被連接到QtGui.QMainWindow的close()槽函數(shù)里。

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

創(chuàng)建了一個QtCore.QObject的子類。 當其初始化時,創(chuàng)建一個名叫closeApp的信號。

self.c = Communicate()
self.c.closeApp.connect(self.close)     

一個Communicate類的實例被創(chuàng)建。我們把closeApp的信號連接到QtGui.QMainWindow的close()槽函數(shù)。

def mousePressEvent(self, event):
    
    self.c.closeApp.emit()

當在窗口上點擊鼠票時, closeApp 信號發(fā)出。

    

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多