我正在阅读“使用Python和Qt进行Rapid Gui编程”一书,并且在信号/插槽项目上遇到了问题。我已经下载了作者代码以与我自己进行比较,但它看起来都一样,但是,当我从派生的旋转框类发出信号时,python就崩溃了。这是我的整个代码:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class ZeroSpinBox(QSpinBox):
zeros = 0
def __init__(self, parent=None):
super(ZeroSpinBox, self).__init__(parent)
self.connect(self, SIGNAL("valueChanged(int)"), self.checkzero)
def checkzero(self):
if self.value() == 0:
self.zeros += 1
self.emit(SIGNAL("atzero"), self.zeros)
class Form(QDialog):
def __init__(self, parent= None):
super(Form, self).__init__(parent)
dial = QDial()
dial.setNotchesVisible(True)
spinbox = ZeroSpinBox()
spinbox.setRange(0,200)
dial.setRange(0,200)
layout = QHBoxLayout()
layout.addWidget(dial)
layout.addWidget(spinbox)
self.setLayout(layout)
self.connect(dial, SIGNAL("valueChanged(int)"), spinbox, SLOT("setValue(int)"))
self.connect(spinbox, SIGNAL("valueChanged(int)"), dial, SLOT("setValue(int)"))
self.connect(spinbox, SIGNAL("atzero"), self.announce)
self.setWindowTitle("Signals and Slots Part 2")
def announce(self, zeros):
print "ZeroSpinBox has been at zero %d times" % zeros
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
我的问题发生在spinbox下降到零时,checkzero(self)方法(ZeroSpinBox类)被调用,self.zeros + = 1行是ok,然后在emit行窗口报告Python。 exe崩溃了。我得到的错误是“python.exe已停止工作”,控制台报告“进程已完成退出代码-1073741819”
知道为什么会这样吗?这是Python 2.7.2和PyQT4 w / PySide。
答案 0 :(得分:4)
在SIGNAL("atzero")
和SIGNAL("atzero(int)")
中用checkzero
替换Form.__init__
,因为您宣布它的方式,它没有任何争议。
编辑:您的代码采用“新式”,
import sys
from PySide.QtCore import *
from PySide.QtGui import *
class ZeroSpinBox(QSpinBox):
zeros = 0
def __init__(self, parent=None):
super(ZeroSpinBox, self).__init__(parent)
self.valueChanged.connect(self.checkzero)
atzero = Signal(int)
def checkzero(self):
if self.value() == 0:
self.zeros += 1
self.atzero.emit(self.zeros)
class Form(QDialog):
def __init__(self, parent= None):
super(Form, self).__init__(parent)
dial = QDial()
dial.setNotchesVisible(True)
spinbox = ZeroSpinBox()
spinbox.setRange(0,200)
dial.setRange(0,200)
layout = QHBoxLayout()
layout.addWidget(dial)
layout.addWidget(spinbox)
self.setLayout(layout)
dial.valueChanged.connect(spinbox.setValue)
spinbox.valueChanged.connect(dial.setValue)
spinbox.atzero.connect(self.announce)
self.setWindowTitle("Signals and Slots Part 2")
@Slot(int)
def announce(self, zeros):
print "ZeroSpinBox has been at zero %d times" % zeros
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
答案 1 :(得分:2)
这是由于PySide和PyQt4之间存在差异,记录为here(实际上,严格来说,这是PySide中的一个错误 - 使用不支持的信号语法形式会产生错误,不会导致应用程序崩溃)。
您使用的书是专为PyQt4编写的,因此您可能需要了解PySide和PyQt4在使用时的区别。例如,请参阅here。
请注意,你的脚本的PyQt4版本工作正常,有或没有信号的括号部分 - 重要的是它们是相同的。但是,这仅适用于用户定义的信号 - 对于预定义的Qt信号和插槽,您必须始终包含签名的带括号的部分。
您应该注意的另一件事是,您使用的信号/插槽语法已经被更加pythonic的新式语法所取代。所以,在某些时候,如果你的书没有涵盖它,那么阅读here所获得的指导是值得的。