我正在读《用Python和Qt快速编程Gui》一书,在信号/插槽项目上遇到了问题。我已经下载了作者的代码来与我自己的代码进行比较,看起来都是一样的,然而,当我从派生的spin-box类发出信号时,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降到零时,(ZeroSpinBox类的)checkzero(self)方法被调用,self.zeros+=1行正常时,我的问题就会出现,然后在发出行窗口报告Python.exe崩溃。我得到的错误是"python.exe已停止工作",控制台报告"进程已完成,退出代码为1073741819"
知道为什么会发生这种事吗?这是Python 2.7.2和PyQT4 w/PySide。
将checkzero
和Form.__init__
中的SIGNAL("atzero")
替换为SIGNAL("atzero(int)")
,因为您声明它的方式没有参数。
编辑:您的代码在"新型",
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_()
这是由于PySide和PyQt4之间的差异,本文对此进行了说明(实际上,严格来说,这是PySide中的一个错误-使用不受支持的信号语法形式应该会产生错误,而不是使应用程序崩溃)。
您正在使用的这本书是专门为PyQt4编写的,因此在使用它时,您可能需要注意PySide和PyQt4之间的差异。例如,请参阅此处。
请注意,PyQt4版本的脚本运行良好,无论是否使用信号的括号部分,重要的是它们是相同的。然而,这仅适用于用户定义的信号-对于预定义的Qt信号和槽,必须始终包括签名的括号部分。
您应该注意的另一件事是,您正在使用的信号/插槽语法已经被一种更Python的新型语法所取代。因此,在某种程度上,如果你的书没有涵盖这一点,那么阅读这里的指南是值得的