How to connect custom signal to slot in pyside wit

2019-02-19 08:55发布

问题:

This is an example from an video tutorial:

#!/usr/bin/env python3

import sys
from PySide.QtCore import *
from PySide.QtGui import *

class ZeroSpinBox(QSpinBox):

    zeros = 0

    def __init__(self):
        super().__init__()
        self.valueChanged.connect(self.checkzero)

    def checkzero(self):
        if self.value() == 0:
            self.zeros += 1
            self.emit(SIGNAL("atzero(int)"), self.zeros)



class Form(QDialog):

    def __init__(self):
        super().__init__()

        dial = QDial()
        dial.setNotchesVisible(True)
        zerospinbox = ZeroSpinBox()
        layout = QHBoxLayout()
        layout.addWidget(dial)
        layout.addWidget(zerospinbox)
        self.setLayout(layout)

        dial.valueChanged.connect(zerospinbox.setValue)
        zerospinbox.valueChanged.connect(dial.setValue)
        # zerospinbox.atzero.connect(self.announce)
        self.connect(zerospinbox, SIGNAL("atzero(int)"), self.announce)

        self.setWindowTitle("Signals")

    def announce(self, zeros):
        print("zerospinbox has been at zero " + str(zeros) + " times.")



app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

Note that I have made two connections for the zerospinbox object, the first one with the new connect syntax, the second one with the old syntax. There is also a line for making the same second connection with the new syntax, but it doesn't work, hence it's commented out. The atzero signal is custom made, and it seems signals made this does not work well with the new syntax. Is this due to the methods of emission? How can I applied the new syntax to the atzero signal as well?

回答1:

Your have to declare new signal in class your implemented or inheritance;

class ZeroSpinBox (QSpinBox):
    atzero = Signal(int)
    .
    .

Then, your can call it in new-style signal. For emit signal;

        self.emit(SIGNAL("atzero(int)"), self.zeros)

Change to

        self.atzero.emit(self.zeros)

For connect signal;

         self.connect(zerospinbox, SIGNAL("atzero(int)"), self.announce)

Change to

         zerospinbox.atzero.connect(self.announce)

Also you can read this document to more information.


Implement code example (PyQt4 also same PySide, different is name Signal & pyqtSignal);

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class ZeroSpinBox(QSpinBox):
    atzero = pyqtSignal(int)

    zeros = 0

    def __init__(self):
        super(ZeroSpinBox, self).__init__()
        self.valueChanged.connect(self.checkzero)

    def checkzero(self):
        if self.value() == 0:
            self.zeros += 1
#             self.emit(SIGNAL("atzero(int)"), self.zeros)
            self.atzero.emit(self.zeros)



class Form(QDialog):

    def __init__(self):
        super(Form, self).__init__()

        dial = QDial()
        dial.setNotchesVisible(True)
        zerospinbox = ZeroSpinBox()
        layout = QHBoxLayout()
        layout.addWidget(dial)
        layout.addWidget(zerospinbox)
        self.setLayout(layout)

        dial.valueChanged.connect(zerospinbox.setValue)
        zerospinbox.valueChanged.connect(dial.setValue)
        zerospinbox.atzero.connect(self.announce)
#         self.connect(zerospinbox, SIGNAL("atzero(int)"), self.announce)

        self.setWindowTitle("Signals")

    def announce(self, zeros):
        print("zerospinbox has been at zero " + str(zeros) + " times.")



app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()