调用应用的 exec_() 方法之后,应用进入主循环。主循环获取事件并把它们发往对象。应用在它的生命周期中产生的不同事件交互。事件主要由用户产生,但是它们也可以由其他方式产生,如:互联网,窗口管理器,定时器,当一个特殊的事件发生时,将发射信号,“槽 ”可以是任何Python调用,当链接到槽的信号发射,该槽将被调用。
在事件模型中,有三个参与者:
event source:事件源,事件来源对象代理了事件的目标要处理的任务
event object:事件对象,指状态改变的对象,它产生了事件。 事件对象 (Event)封装了事件源的状态改变。
event target:事件目标,事件对象想要想要通知的对象,貌似这个不是必须的。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class LcdSlider(QtGui.QWidget): def __init__(self): super(LcdSlider, self).__init__() self.initUI() def initUI(self): lcd = QtGui.QLCDNumber(self) # 初始化数字LCD面板 slider = QtGui.QSlider(QtCore.Qt.Horizontal, self) # 初始化水平滑块 vbox = QtGui.QVBoxLayout() vbox.addWidget(lcd) vbox.addWidget(slider) self.setLayout(vbox) self.connect(slider, QtCore.SIGNAL('valueChanged(int)'), lcd, QtCore.SLOT('display(int)')) # 滑块为事件源,当滑块收到valuechange(int)的信号之后,lcd的被指定的“槽”display(int)会被调用 self.setWindowTitle('Signal & slot') self.resize(250, 150) app = QtGui.QApplication(sys.argv) ex = LcdSlider() ex.show() sys.exit(app.exec_())
connect方法有4个参数,sender是发送信号的对象,signal是发射的信号,receiver是接收信号的对象,slog是对信号反应的方法。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class EscapeExample(QtGui.QWidget): def __init__(self): super(EscapeExample, self).__init__() self.setWindowTitle('Escape') self.resize(250, 150) # 重新实现指定按钮被按下的事件处理程序 def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.close() app = QtGui.QApplication(sys.argv) ex = EscapeExample() ex.show() sys.exit(app.exec_())
重新实现了 keyPressEvent() 处理。按下ESC会自动退出。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class SenderExample(QtGui.QMainWindow): def __init__(self): super(SenderExample, self).__init__() self.initUI() def initUI(self): button1 = QtGui.QPushButton("Button 1", self) button1.move(30, 50) button2 = QtGui.QPushButton("Button 2", self) button2.move(150, 50) # 接收到clicked信号时调用buttonClicked self.connect(button1, QtCore.SIGNAL('clicked()'), self.buttonClicked) self.connect(button2, QtCore.SIGNAL('clicked()'), self.buttonClicked) self.statusBar().showMessage('Ready') self.setWindowTitle('Event sender') self.resize(290, 150) def buttonClicked(self): sender = self.sender() # sender可用来获取信号源 self.statusBar().showMessage(sender.text() + ' was pressed') app = QtGui.QApplication(sys.argv) ex = SenderExample() ex.show() sys.exit(app.exec_())
两个按钮都连接了同一个信号,按钮被按下的时候状态栏会显示按钮的标签。
自定义信号:
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class EmitExample(QtGui.QWidget): def __init__(self): super(EmitExample, self).__init__() self.initUI() def initUI(self): # 自己创建一个信号,接收后关闭程序 self.connect(self, QtCore.SIGNAL('closeEmitApp()'), QtCore.SLOT('close()')) self.setWindowTitle('emit') self.resize(250, 150) def mousePressEvent(self, event): # 通过 emit() 方法发射信号 self.emit(QtCore.SIGNAL('closeEmitApp()')) app = QtGui.QApplication(sys.argv) ex = EmitExample() ex.show() sys.exit(app.exec_())
单击鼠标程序会关闭。