GUI 的程序开发人员并非需要甚至根本不需要知道所有的控件实现的底层细节,我们只需要知道当按钮按下时能够适当的相应即可。基于这一原因,Qt 和 pyqt 提供了两种通信机制:低级事件处理机制和高级事件处理机制,前者与其他 GUI 库提供的功能类似,或者被称之为 “信号与槽”。
QT 的一个关键特性是它使用信号和槽来进行对象之间的通讯。当一个组件发出一个信号时,一个可用的插槽应应该做出相应。如果一个信号连接到一个插槽,那么当信号被发射时,该插槽应该被调用。如果信号没有连接,则不会发生任何事情。
信号与槽机制的特点
- 信号可能连接到很多插槽
- 信号也可能连接到另外一个信号
- 信号参数可以是任何 python 类型
- 一个插槽可能连接到许多信号
- 连接可以是直接的 (同步) 也可是是排队的 (异步)
- 连接可以跨线程
- 连接可能中断
绑定和未绑定信号
信号(特别是非绑定信号)是作为 QObject 子类的类的属性。一个绑定信号具有connect(),disconnect()和emit()实现相关联的功能的方法。要截取一个信号必须把它连接到槽上。
连接信号与槽的语法形式
QtCore.QObject.connect(a, QtCore.SIGNAL('QtSig()'), pyFunction)
QtCore.QObject.connect(a, QtCore.SIGNAL('QtSig()'), pyClass.pyMethod)
QtCore.QObject.connect(a, QtCore.SIGNAL('QtSig()'), b, QtCore.SLOT('QtSlot()'))
QtCore.QObject.connect(a, QtCore.SIGNAL('PySig()'), b, QtCore.SLOT('QtSlot()'))
QtCore.QObject.connect(a, QtCore.SIGNAL('PySig'), pyFunction)
以上语法可以理解为:连接 a 对象的信号到槽函数或者某个 b 对象的某个函数。
发射信号与槽的语法
a.emit(QtCore.SIGNAL('clicked()'))
a.emit(QtCore.SIGNAL('pySig'), "Hello", "World")
发射一个信号,也可以带参数。
内置的信号与槽
大部分的窗口控件都提前预置了一些槽,所以很多时候可以直接把预置的信号和预置的槽相连接,无需做任何事情就可以得到想要的行为效果。
下面我们看两个简单的窗口部件 Dial 和 SpinBox。这两个窗口部件都有 valueChange() 信号,当这个信号触发时就会带有新值。这两个窗口部件也都有 setValue() 槽,带有整数型参数。因此可以将两个部件的信号和槽连接起来,无论用户改变哪一个窗口部件,都会让另一个值做出改变。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'D:\pyqtSingAndSloft\SingSloftDialog.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate