2013-07-21 70 views
0

嗯,我熟悉Qt,但是當使用PyQt時,信號/插槽的語法真的讓我困惑。 當使用C++/Qt時,編譯器會給你一個提示,你對信號/插槽的錯誤信息,但是PyQt的默認配置沒有提供有關錯誤的提示。有沒有一種方式或諸如調試觸發模式來使PyQt顯示更多信息? 代碼是如下:處理用戶定義信號/插槽時PyQt和Qt的區別

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的::連接返回值將顯示信號/槽結合是成功與否。在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

首先,你應該真的使用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_()