PySide学习笔记第八章-事件和信号

时间:2022-11-22 07:35:22

下面我们探索下应用中的事件和信号

一、事件

在GUI编程中,事件是很重要的一部分,事件是由系统或用户产生的,当我们调用应用的 exec_()函数的时候,应用进入主循环,主循环获取事件然后将事件信息传递给对象,Qt具有独特的信号槽机制( signal and slot mechanism)

所有的GUI应用都是事件驱动的,一个应用在其生存过程中对不同的事件类型做出响应,事件主要是由操作应用的用户产生的,但是也可以以其他的任何方式产生,例如:因特网联接,窗口管理器,计时器。在事件模型中,它们都是参与者:

事件源

事件对象

事件目标

信号源是一个对象,而这个对象的状态可以改变。它产生事件,事件源(Event对象)将状态改变封装在内部。事件目标是事件对象想要通知的目标。信号槽机制就是用来在不同的对象之间进行信息交流的。当一个特定的事件发生时,信号被释放,槽 可以是任何python可以调用的东西,当一个释放的信号和一个槽联系起来后,信号一旦释放,该槽酒会被调用

二、信号槽机制

下面是对PySide (Qt)的信号槽机制的一个简单演示

# -*- coding: utf-8 -*-

"""
ZetCode PySide 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: August 2011
"""

import sys
from PySide import QtGui, QtCore

class Example(QtGui.QWidget):

def __init__(self):
super(Example, self).__init__()

self.initUI()

def initUI(self):

lcd = QtGui.QLCDNumber(self) # 创建一个LCD表盘
sld = QtGui.QSlider(QtCore.Qt.Horizontal, self) # 创建一个水平滑动轴

vbox = QtGui.QVBoxLayout() # 创建一个竖直框布局类,用于放置lcd,sld
vbox.addWidget(lcd)
vbox.addWidget(sld)

self.setLayout(vbox)
sld.valueChanged.connect(lcd.display) # 将滑动轴被拖动的事件(信号)和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()
三、重新实现事件处理函数

在PySide(Qt)中,事件都是通过重新定义事件处理函数的方式来处理

这里重新定义了keyPressEvent()函数 ,对于每一个窗口都会有一个默认的keyPressEvent()函数继承于QtGui.QWidget,这里重新定义了该函数,使得点击esc键的时候退出当前窗口

四、事件发送者 Event sender

有时候我们可以很方便的知道,哪一个widget是信号的发送者,PySide有一个sender()函数


在本示例中,演示 信号的发出者

import sys
from PySide 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) # 将特定按钮的点击(信号) 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()
5 、释放信号

由QtCore.QObject创建的对象可以释放信号,如果我们点击button,就会产生一个信号(无论你接受与否)在下面的代码中我们会看到,如何释放一个自定义的信号

def mousePressEvent(self, event): # 我们自定义一个信号叫做closeApp只要在窗口内点击鼠标都会释放一个信号
        
        self.c.closeApp.emit()

# -*- coding: utf-8 -*-

"""
ZetCode PySide tutorial

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

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

import sys
from PySide import QtGui, QtCore

class Communicate(QtCore.QObject):

closeApp = QtCore.Signal() # 创建一个信号: closeApp

class Example(QtGui.QMainWindow):

def __init__(self):
super(Example, self).__init__()

self.initUI()

def initUI(self):

self.c = Communicate() # 基于QtCore.QObject我们创建一个类,当该类实例化的时候创建closeApp信号
self.c.closeApp.connect(self.close) # closeApp信号和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()