python pyqt5 自定义信号和槽

Python010

python pyqt5 自定义信号和槽,第1张

"""

【简介】

内置信号槽示例

"""

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以後的版本。 建议您开始使用这种新的方式吧。