"""
【简介】
内置信号槽示例
"""
from PyQt5.QtCore import QObject, pyqtSignal
class QTypeSignal(QObject):
# 定义一个信号
sendmsg = pyqtSignal(object)
class QTypeSlot(QObject):
def init (self):
super(QTypeSlot, self). init ()
if name == ' main ':
send = QTypeSignal()
slot = QTypeSlot()
# 1
print('--- 把信号绑定到槽函数 ---')
send.sendmsg.connect(slot.get)
send.run()
from PyQt5.QtCore import QObject , pyqtSignal
class QTypeSignal(QObject):
#定义一个信号
sendmsg = pyqtSignal( str,str)
class QTypeSlot(QObject):
def init ( self):
super( QTypeSlot, self). init ()
if name == ' main ':
send = QTypeSignal()
slot = QTypeSlot()
如果你是使用PyQT 4.5之後的版本,除了传统的signal/slot的连接方式外,你还多了一种比较符合Python样式的写法。 这种写法是透过下面两种新的PyQT物件来达成pyqtSignal
pyqtSlot
正如其名, pyqtSingal是用来定义signal,而pyqtSlot 则是用於slot。
首先,我们来了解如何利用pyqtSignal来制定一个signal。
qt的官方文档中有说明,signal只能在QObject的子类中定义。如果在子类外直接定义,会出现 AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'emit'
且看下面的范例:
from PyQt4 import QtCore
class MyQObject(QtCore.QObject):
# 定义一个无参数的signal
signal1 = QtCore.pyqtSignal()
# 定义一个有一个整数参数的signal,并且name为qtSignal2。
signal2 = QtCore.pyqtSignal(int, name='qtSignal2')
def __init__(self):
super(MyQObject, self).__init__() #如果写了__init__()函数,这一行一定要有,否则会出现TypeError: pyqtSignal must be bound to a QObject, not 'MyQObject'
def connectSigSlot(self):
# 利用pySignal物件本身提供的connect,我们可以轻易的将pySignal物件与对应的slot相连。
# 将signal1与myReceiver1连接起来。
self.signal1.connect(self.myReceiver1)
# 将signal2与myReceiver2连接起来。
self.signal2.connect(self.myReceiver2)
def myEmitter(self):
# 利用pyqtSignal物件所提供的emit function,我们就可以轻易的发出signal。
self.signal1.emit()
self.signal2.emit(10)
def myReceiver1(self):
print 'myReceiver1 called'
def myReceiver2(self, arg):
print 'myReceiver2 called with argument value %d' % arg
简单的说,透过pyqtSignal,将signal也视为一种物件,所以signal所需的功能皆可由signal本身的method来定义。 所以整个signal的定义与使用完全符合物件导向的精神,程式看起来也更为直觉。
而pySlot则是一个Python的decorator,我们可以透过他来将一个method定义为slot。
@QtCore.pyqtSlot
()
def mySlot(self):
print 'mySlot received a signal')
@QtCore.pyqtSlot
(int)
def mySlot2(self, arg):
print 'mySlot2 received a signal with argument %d' % arg)
整个slot的定义与旧的方法相较,顿时变得简单许多。如果,你的UI使透过pyuic4所制作出来的,那 甚至可以透过
slot的名称来指定要连结的元件与signal。举例来说,如果你的UI中有一个名为myBtn的按钮,想要连接他的clicked
signal。你只要在你继承的视窗类别中,定义如下的slot:
@QtCore.pyqtSlot
(bool)
def on_myBtn_clicked(self, checked):
print 'myBtn clicked.'
PyQT会自动将这个slot与UI内的myBtn的clicked singal连接起来。真的是非常省事。
新的singal/slot的定义与使用方式是PyQT 4.5中的一大改革。可以让PyQT程式更清楚易读。如果你也是用PyQT 4.5以後的版本。 建议您开始使用这种新的方式吧。