好吧,我对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()'))
答案 0 :(得分:1)
首先,您应该将new style signals与pyqt结合使用。事实上,QObject.connect
和QObject.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_()