来源:http://blog.youkuaiyun.com/hlqyq/article/details/6713828
注意,原文有些错误
1、信号定义
通过类成员变量定义信号对象,如:
class MyWidget(QWidget):
Signal_NoParameters = PyQt4.QtCore.pyqtSignal() # 无参数信号
Signal_OneParameter = PyQt4.QtCore.pyqtSignal(int) # 一个参数(整数)的信号
Signal_OneParameter_Overload = PyQt4.QtCore.pyqtSignal([int],[str]) # 一个参数(整数或者字符串)重载版本的信号
Signal_TwoParameters = PyQt4.QtCore.pyqtSignal(int,str) # 二个参数(整数,字符串)的信号
Signal_TwoParameters_Overload = PyQt4.QtCore.pyqtSignal([int,int],[int,str]) # 二个参数([整数,整数]或者[整数,字符串])重载版本的信号
注意:虽然写的是str,实际发送的是QString类型
AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'emit'
不要把信号定义在__init__里面
参考:http://stackoverflow.com/questions/2970312/pyqt4-qtcore-pyqtsignal-object-has-no-attribute-connect
2、信号焕发
通过pyqtSignal对象的emit方法焕发事件,如:
class MyWidget(QWidget):
...
def mousePressEvent(self, event):
self.Signal_NoParameters.emit() # 焕发无参数信号
self.Signal_OneParameter.emit(1) # 焕发一个参数(整数)的信号
self.Signal_OneParameter_Overload.emit(1) # 焕发一个参数(整数)重载版本的信号
self.Signal_OneParameter_Overload[str].emit("abc") # 焕发一个参数(字符串)重载版本的信号
self.Signal_TwoParameters.emit(1,"abc") # 焕发二个参数(整数,字符串)的信号
self.Signal_TwoParameters_Overload.emit(1,2) # 焕发二个参数(整数,整数)重载版本的信号
self.Signal_TwoParameters_Overload[int,str].emit(1,"abc") # 焕发二个参数(整数,字符串)重载版本的信号
注意,如果不写[str],或调用默认的
3、槽函数定义
通过@PyQt4.QtCore.pyqtSlot装饰方法定义槽函数,如:
class MyWidget(QWidget):
...
@PyQt4.QtCore.pyqtSlot()
def setValue_NoParameters(self):
'''''无参数槽方法'''
pass
@PyQt4.QtCore.pyqtSlot(int)
def setValue_OneParameter(self,nIndex):
'''''一个参数(整数)槽方法'''
pass
@PyQt4.QtCore.pyqtSlot(str)
def setValue_OneParameter_String(self,szIndex):
'''''一个参数(字符串)的槽方法'''
pass
@PyQt4.QtCore.pyqtSlot(int,int)
def setValue_TwoParameters(self,x,y):
'''''二个参数(整数,整数)槽方法'''
pass
@PyQt4.QtCore.pyqtSlot(int,str)
def setValue_TwoParameters_String(self,x,szY):
'''''二个参数(整数,字符串)槽方法'''
pass
注意:PyQt4.QtCore.pyqtSlot 好像不是必须的,文档说有些情况需要,没完全理解。
4、信号连接
通过pyqtSignal的connect方法连接信号和槽方法或者可调用对象,如:
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
widget.Signal_NoParameters.connect(self.setValue_NoParameters,Qt.QueuedConnection) # 连接无参数信号
widget.Signal_OneParameter.connect(self.setValue_OneParameter,Qt.QueuedConnection) # 连接一个参数(整数)信号
widget.Signal_OneParameter_Overload[int].connect(self.setValue_OneParameter,Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
widget.Signal_OneParameter_Overload[str].connect(self.setValue_OneParameter_String,Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
widget.Signal_TwoParameters.connect(self.setValue_TwoParameters,Qt.QueuedConnection) # 连接二个参数(整数)信号
widget.Signal_TwoParameters_Overload[int,int].connect(self.setValue_TwoParameters,Qt.QueuedConnection) # 连接二个参数(整数,整数)重载版本信号
widget.Signal_TwoParameters_Overload[int,str].connect(self.setValue_TwoParameters_String,Qt.QueuedConnection) # 连接二个参数(整数,字符串)重载版本信号
5、实例
# coding=gbk
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyWidget(QWidget):
OnClicked = pyqtSignal([int,int],[int,str])
def __init__(self, parent=None):
super(MyWidget,self).__init__(parent)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.OnClicked.emit(event.x(),event.y())
event.accept()
elif event.button() == Qt.RightButton:
self.OnClicked[int,str].emit(event.x(),str(event.y()))
event.accept()
else:
super(MyWidget,self).mousePressEvent(self, event)
def OnValueChanged_int(x,y):
print("左键(%d,%d)" % (x,y))
def OnValueChanged_string(szX,szY):
print('右键(' + str(szX) + ',' + szY + ')')
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
widget.OnClicked.connect(OnValueChanged_int,Qt.QueuedConnection)
widget.OnClicked[int,str].connect(OnValueChanged_string,Qt.QueuedConnection)
sys.exit(app.exec_())
super(MyQObject, self).__init__() #如果写了__init__()函数,这一行一定要有,否则会出现 #TypeError: pyqtSignal must be bound to a QObject, not 'MyQObject'
完整的测试代码:
#!/usr/bin/env python
#coding:utf8
__version__ = "1.0"
"""
《New-style Signal and Slot Support》文档的测试程序
- sofire@gmail.com @2013.02.11
http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
注意:
1、str和QString的关系没弄明白
2、@QtCore.pyqtSlot() 的作用不清楚
"""
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui
from PyQt4.QtCore import QVariant
import os, sys, time
def pyFunction():
print "pyFunction"
def pyFunction2(i):
print "pyFunction", i
class TestWidget(QWidget):
"""
信号的定义
注意不要定义到__init__等方面里了,否则会报错
"""
Signal_NoParameters = QtCore.pyqtSignal() # 无参数信号
Signal_OneParameter = QtCore.pyqtSignal(int) # 一个参数(整数)的信号
Signal_OneParameter_Overload = QtCore.pyqtSignal([int],[str]) # 一个参数(整数或者字符串)重载版本的信号
Signal_OneParameter_Overload2 = QtCore.pyqtSignal([int],['QString']) # 一个参数(整数或者字符串)重载版本的信号
Signal_TwoParameters = QtCore.pyqtSignal(int,str) # 二个参数(整数,字符串)的信号
Signal_TwoParameters_Overload = QtCore.pyqtSignal([int,int],[int,str]) # 二个参数([整数,整数]或者[整数,字符串])重载版本的信号
def __init__(self, parent=None):
super(TestWidget, self).__init__(parent)
#信号连接
self.Signal_NoParameters.connect(self.setValue_NoParameters, Qt.QueuedConnection) # 连接无参数信号
self.Signal_OneParameter.connect(self.setValue_OneParameter, Qt.QueuedConnection) # 连接一个参数(整数)信号
self.Signal_OneParameter_Overload[int].connect(self.setValue_OneParameter, Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
self.Signal_OneParameter_Overload[str].connect(self.setValue_OneParameter_String, Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
self.Signal_OneParameter_Overload2[int].connect(self.setValue_OneParameter2, Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
self.Signal_OneParameter_Overload2[str].connect(self.setValue_OneParameter2, Qt.QueuedConnection) # 连接一个参数(整数)重载版本信号
self.Signal_TwoParameters.connect(self.setValue_TwoParameters, Qt.QueuedConnection) # 连接二个参数(整数)信号
self.Signal_TwoParameters_Overload[int,int].connect(self.setValue_TwoParameters, Qt.QueuedConnection) # 连接二个参数(整数,整数)重载版本信号
self.Signal_TwoParameters_Overload[int,str].connect(self.setValue_TwoParameters_String, Qt.QueuedConnection) # 连接二个参数(整数,字符串)重载版本信号
#self.runTest()
"""
信号Emit
"""
def mousePressEvent(self, event):
self.Signal_NoParameters.emit() # 焕发无参数信号
self.Signal_OneParameter.emit(1) # 焕发一个参数(整数)的信号
self.Signal_OneParameter_Overload.emit(2) # 焕发一个参数(整数)重载版本的信号
self.Signal_OneParameter_Overload[int].emit(3) # 焕发一个参数(整数)重载版本的信号
self.Signal_OneParameter_Overload[str].emit("abc") # 焕发一个参数(字符串)重载版本的信号
self.Signal_OneParameter_Overload2.emit(22) # 焕发一个参数(整数)重载版本的信号
self.Signal_OneParameter_Overload2[int].emit(33) # 焕发一个参数(整数)重载版本的信号
self.Signal_OneParameter_Overload2[str].emit("abcabc") # 焕发一个参数(字符串)重载版本的信号
self.Signal_TwoParameters.emit(1,"abc") # 焕发二个参数(整数,字符串)的信号
self.Signal_TwoParameters_Overload[int,int].emit(1,2) # 焕发二个参数(整数,整数)重载版本的信号
self.Signal_TwoParameters_Overload[int,str].emit(1,"abc") # 焕发二个参数(整数,字符串)重载版本的信号
@QtCore.pyqtSlot()
def setValue_NoParameters(self):
'''''无参数槽方法'''
print "setValue_NoParameters"
pass
@QtCore.pyqtSlot(int)
def setValue_OneParameter(self, nIndex):
'''''一个参数(整数)槽方法'''
print "setValue_OneParameter", nIndex
pass
@QtCore.pyqtSlot(str)
def setValue_OneParameter_String(self, szIndex):
'''''一个参数(字符串)的槽方法'''
print "setValue_OneParameter_String", szIndex
pass
#@QtCore.pyqtSlot(int)
@QtCore.pyqtSlot('QString')
@QtCore.pyqtSlot(str)
def setValue_OneParameter2(self, i):
#print type(i)
if isinstance(i, QtCore.QString):
print 'setValue_OneParameter2 is str', i
elif isinstance(i, int):
print 'setValue_OneParameter2 is int', i
else:
print 'wrong type'
@QtCore.pyqtSlot(int,int)
def setValue_TwoParameters(self, x, y):
'''''二个参数(整数,整数)槽方法'''
print "setValue_TwoParameters", x, y
pass
@QtCore.pyqtSlot(int,str)
def setValue_TwoParameters_String(self, x, szY):
'''''二个参数(整数,字符串)槽方法'''
print "setValue_TwoParameters_String", x, szY
pass
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
widget = TestWidget()
widget.show()
app.exec_()