PySide 发出信号导致 python 崩溃

发布于 2024-12-25 22:59:24 字数 1678 浏览 4 评论 0原文

我正在阅读《使用 Python 和 Qt 进行快速 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_()

当旋转盒降到零时,出现问题,调用 checkzero(self) 方法(ZeroSpinBox 类的), self.zeros += 1 行正常,然后发出line windows 报告 Python.exe 已崩溃。我收到的错误是“python.exe 已停止工作”,控制台报告“进程已完成,退出代码 -1073741819”

知道为什么会发生这种情况吗?这是 Python 2.7.2 和 PyQT4 w/PySide。

I am working through the book "Rapid Gui Programming with Python and Qt" and am having a problem on the signals/slots project. I have downloaded the authors code to compare against my own, and it all looks the same, however, when I emit a signal from a derived spin box class, python just crashes. Here is the entire code that I have:

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_()

My problem occurs when the spinbox goes down to zero, the checkzero(self) method (of the ZeroSpinBox class) gets called, the self.zeros += 1 line is ok, then on the emit line windows reports that Python.exe has crashed. The error I get is "python.exe has stopped working" and the console reports "Process finished with exit code -1073741819"

Any idea why this is happening? This is Python 2.7.2 and PyQT4 w/PySide.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝颜夕 2025-01-01 22:59:24

checkzeroForm.__init__< 中将 SIGNAL("atzero") 替换为 SIGNAL("atzero(int)") /code>,因为您声明它的方式,它不带有任何参数。

编辑:你的代码在“新风格”中,

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_()

Substitute SIGNAL("atzero") with SIGNAL("atzero(int)") both in checkzero and in Form.__init__, because the way you're declaring it, it carries no argument.

Edit: your code in the "new-style",

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_()
≈。彩虹 2025-01-01 22:59:24

这是由于 PySide 和 PyQt4 之间的差异造成的,此处记录了该差异(实际上,严格来说, ,这是 PySide 中的一个错误 - 使用不受支持的信号语法的形式应该产生错误,而不是使应用程序崩溃)。

您正在使用的这本书是专门为 PyQt4 编写的,因此您在使用它时可能需要了解 PySide 和 PyQt4 之间的差异。例如,请参阅此处

请注意,无论有或没有信号的括号部分,脚本的 PyQt4 版本都可以正常工作 - 重要的是它们是相同的。但是,这只适用于用户定义信号 - 对于预定义的 Qt 信号和槽,您必须始终包含签名的括号部分。

您应该注意的另一件事是,您正在使用的信号/槽语法已被更加Pythonic的新型语法所取代。因此,在某些时候,阅读此处的指南是值得的,如果你的书没有涵盖它。

This due to a difference between PySide and PyQt4, which is documented here (actually, strictly speaking, this is a bug in PySide - using a unsupported form of signal syntax should produce an error, not crash the application).

The book you are using was written specifically for PyQt4, and so you probably need to be aware of the differences between PySide and PyQt4 when using it. See here, for example.

Note that the PyQt4 version of your script works fine, with or without the parenthesized portion of the signal - all that matters is that they are the same. However, this is only true for user-defined signals - for predefined Qt signals and slots, you must always include the parenthesized portion of the signature.

Another thing you should be aware of, is that the signal/slot syntax you are using has been superceeded by a much more pythonic new-style syntax. So, at some point, it would be worthwhile reading through the guidance found here, if your book doesn't cover it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文