`
sofire
  • 浏览: 143824 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

New-style Signal and Slot 学习笔记[转]

 
阅读更多

 来源:http://blog.csdn.net/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_()

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics