PySide发出信号导致python崩溃



我正在读《用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。

checkzeroForm.__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的新型语法所取代。因此,在某种程度上,如果你的书没有涵盖这一点,那么阅读这里的指南是值得的

最新更新