处理用户定义的信号/槽时PyQt和Qt之间的差异

时间:2013-07-21 12:05:36

标签: pyqt signals slot

好吧,我对Qt很熟悉,但是在使用PyQt时,signal / slot的语法让我很困惑。 当使用C ++ / Qt时,编译器会给你一个提示你信号/插槽错误的提示,但是PyQt默认配置没有提供有关错误的提示。是否有调试触发模式等方式使PyQt能够显示更多信息? 守则如下:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time

class workThread(QThread):

    def __init__(self,parent = None):
        super(workThread,self).__init__(parent)
        self.mWorkDoneSignal = pyqtSignal() ## some people say this should be defined as clas member, however, I defined it as class member and still fails.

    def run(self):
        print "workThread start"
        time.sleep(1)
        print "workThread stop"
        print self.emit(SIGNAL("mWorkDoneSignal"))

class MainWidget(QWidget):
    def __init__(self , parent = None):
        super(MainWidget,self).__init__(parent)

    @pyqtSlot()
    def display(self):
        print "dispaly"

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    c = workThread()
    d = MainWidget()
    ##In Qt, when using QObject::connect or such things, the return value will show the 
    ## signal/slot binding is success or failed
    print QObject.connect(c,SIGNAL('mWorkDoneSignal()'),d,SLOT('display()'))
    c.start()
    d.show()
    app.exec_()

在C ++中,QObject :: connect返回值将显示信号/插槽绑定是否成功。在PyQt中,返回值为True,但它不会触发插槽。 我的问题: 1)信号应该是集体成员还是实例成员? 2)如果QObject.connect的返回值无法给出绑定的提示是否成功,是否还有其他方法可以检测到它?    我想绑定信号发送器和插槽接收器外的信号/插槽,所以我更喜欢使用QObject.connect方式。但是我怎么能写出这个正确的,我尝试了以下方法,都失败了。

 QObject.connect(c,SIGNAL('mWorkDoneSignal'),d,SLOT('display'))
 QObject.connect(c,SIGNAL('mWorkDoneSignal()'),d,SLOT('display()'))

1 个答案:

答案 0 :(得分:1)

首先,您应该将new style signals与pyqt结合使用。事实上,QObject.connectQObject.emit将不再存在in PyQt5

def __init__(self,parent = None):
    super(workThread,self).__init__(parent)
    self.mWorkDoneSignal = pyqtSignal()

这会创建一个未绑定的信号,并将其分配给实例变量mWorkDoneSignal,但它确实没有效果。如果你想创建一个信号,那么你真的必须在课堂上声明它。

所以,如果你没有真正在这里创建一个信号,那么为什么这个调用会成功:

QObject.connect(c,SIGNAL('mWorkDoneSignal()'),d,SLOT('display()'))

答案在于PyQt4的handling of old style signals

  

发出PyQt4信号的行为隐含地定义了它。

因此,当您将信号连接到插槽时,仅检查插槽是否存在。信号本身并不需要在此时存在,因此除非插槽不存在,否则呼叫将始终成功。

  

我尝试了以下方法,都失败了。

QObject.connect(c,SIGNAL('mWorkDoneSignal'),d,SLOT('display'))
QObject.connect(c,SIGNAL('mWorkDoneSignal()'),d,SLOT('display()'))

第一个失败,因为display(没有括号)不是有效的插槽 第二个成功。它不起作用的原因是你发出mWorkDoneSignal,但实际需要发出的是:

self.emit(SIGNAL("mWorkDoneSignal()"))

使用新的风格信号,没有办法解决这个问题:

from utils import sigint
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time

class workThread(QThread):

    mWorkDoneSignal = pyqtSignal()

    def __init__(self,parent = None):
        super(workThread,self).__init__(parent)

    def run(self):
        print "workThread start"
        time.sleep(1)
        print "workThread stop"
        self.mWorkDoneSignal.emit()

class MainWidget(QWidget):
    def __init__(self , parent = None):
        super(MainWidget,self).__init__(parent)

    @pyqtSlot()
    def display(self):
        print "dispaly"

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    c = workThread()
    d = MainWidget()
    c.mWorkDoneSignal.connect(d.display)
    c.start()
    d.show()
    app.exec_()