PySide发出信号导致python崩溃

2024-09-24 06:24:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在阅读《使用Python和Qt快速Gui编程》一书,在signals/slots项目中遇到了一个问题。我已经下载了作者的代码来与我自己的代码进行比较,但是,当我从一个派生的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降为0时,checkzero(self)方法(属于ZeroSpinBox类)被调用时自我零+=1行正常,则在“发射线”窗口上报告Python.exe已经崩溃了。我得到的错误是“python.exe“已停止工作”,控制台报告“进程结束,退出代码为-1073741819”

知道为什么会这样吗?这是python2.7.2和PyQT4 w/PySide。在


Tags: 代码importselfsignalinitdefconnectzeros
2条回答

checkzero和{}中的SIGNAL("atzero")替换{},因为按照您声明它的方式,它没有参数。在

编辑:你的代码在“新样式”

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之间的差异造成的,PyQt4被记录为here(实际上,严格地说,这是PySide中的一个错误-使用不受支持的信号语法形式应该会产生错误,而不是使应用程序崩溃)。在

您正在使用的这本书是专门为PyQt4编写的,因此在使用它时,您可能需要注意PySide和PyQt4之间的区别。例如,请参见here。在

请注意,您的脚本的PyQt4版本可以很好地工作,不管有没有带圆括号的信号部分,重要的是它们是相同的。但是,这只适用于用户定义的信号-对于预定义的Qt信号和时隙,必须始终包含签名的括号部分。在

另一件事你应该知道,你正在使用的signal/slot语法已经被一种更加python的新型语法所取代。所以,在某一点上,如果你的书没有涵盖它的话,它将是值得阅读的指南找到here。在

相关问题 更多 >