Сигнал PySide Emit вызывает сбой Python - PullRequest
1 голос
/ 10 января 2012

Я работаю над книгой "Rapid Gui Programming с Python и Qt" и у меня возникла проблема с проектом сигналов / слотов. Я скачал код авторов для сравнения с моим собственным, и все выглядит одинаково, однако, когда я посылаю сигнал из производного класса 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 падает до нуля, вызывается метод checkzero (self) (из класса ZeroSpinBox), строка self.zeros + = 1 в порядке, затем в строке emit сообщается, что Python. exe разбился. Я получаю сообщение об ошибке: «python.exe перестал работать», и консоль сообщает «Процесс завершен с кодом выхода -1073741819»

Есть идеи, почему это происходит? Это Python 2.7.2 и PyQT4 с PySide.

Ответы [ 2 ]

4 голосов
/ 10 января 2012

Замените 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_()
2 голосов
/ 10 января 2012

Это связано с разницей между PySide и PyQt4, которая задокументирована здесь (собственно, строго говоря, это ошибка в PySide - использование неподдерживаемой формы синтаксиса сигнала должно приводить к ошибке, а не к аварийному завершению приложение).

Книга, которую вы используете, была написана специально для PyQt4, поэтому вам, вероятно, следует помнить о различиях между PySide и PyQt4 при ее использовании. См. здесь , например.

Обратите внимание, что версия вашего скрипта PyQt4 работает нормально, с частью сигнала в скобках или без нее - все, что имеет значение, это то, что они одинаковы. Однако это верно только для определяемых пользователем сигналов - для предварительно определенных сигналов Qt и слотов вы всегда должны включать часть подписи в скобках.

Еще одна вещь, о которой вы должны знать, это то, что используемый вами синтаксис сигнала / слота был заменен гораздо более питоническим синтаксисом нового стиля. Итак, в какой-то момент было бы целесообразно прочитать руководство, найденное здесь , если ваша книга не охватывает его.

...