午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

PyQt4 教程(5)

 學(xué)海無(wú)涯GL 2014-10-24

PyQt4 中的事件與信號(hào)

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

事件

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

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


  • 事件源(event source)
  • 事件對(duì)象(event object)
  • 事件目標(biāo)(event target)

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

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

新 API

PyQt4.5 引入信號(hào)與槽的一種新的API 風(fēng)格。

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

上邊是老式的API

button.clicked.connect(self.onClicked)

這是新式的更符合python標(biāo)準(zhǔn)。

信號(hào)&槽

這是一個(gè)展示PyQt4中的信號(hào)與槽。

#!/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鍵,程序結(jié)束。

事件發(fā)送者

有時(shí)候需要知道信號(hào)的發(fā)送者,為了方便使用PyQt4 有一個(gè) 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()

在我們例子里有兩個(gè)按鈕。在 buttonClicked()方法里我們判斷哪個(gè)按鈕被按下使用了sender()

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

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

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

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


Event sender
Figure: Event sender

發(fā)出信號(hào)

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

#!/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)建了一個(gè)名叫closeApp的信號(hào)。當(dāng)鼠標(biāo)按下時(shí),信號(hào)發(fā)出。信號(hào)被連接到QtGui.QMainWindow的close()槽函數(shù)里

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

創(chuàng)建了一個(gè)QtCore.QObject的子類。 當(dāng)其初始化時(shí),創(chuàng)建一個(gè)名叫closeApp的信號(hào)。

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

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

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

當(dāng)在窗口上點(diǎn)擊鼠票時(shí), closeApp 信號(hào)發(fā)出。

    

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多