Search code examples
pythonpyqt4signals-slots

pyqt auto connect signal


I want use the autoconnection feature. I am using this example:

http://www.eurion.net/python-snippets/snippet/Connecting%20signals%20and%20slots.html

it works, but I want to create my own signals and own slots, the example using built in signals.

for example, here are a custom signal with a custom slot, but don't works:

import sys
from PyQt4 import QtGui, QtCore

class SignalsAndSlots(QtGui.QWidget):

    testSignal = QtCore.pyqtSignal(str,name='testSignal')  



    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setObjectName('testObject')
        self.label = QtGui.QLabel(self)

        QtCore.QMetaObject.connectSlotsByName(self)
        self.emitSignal()


    def emitSignal(self):
        self.testSignal.emit('message')  

    @QtCore.pyqtSlot(str,name='on_testObject_testSignal')     
    def autoSlot(self,msg):
        self.label.setText(msg)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    gui = SignalsAndSlots()
    gui.show()
    app.exec_()

Thanks a lot


Solution

  • Ber is right. This what the pyqt documentation says:

    QMetaObject.connectSlotsByName searches recursively for all child objects of the given object [...]

    Here is a simple example with custom signals :

    import sys
    from PyQt4 import QtGui, QtCore
    
    class CustomButton(QtGui.QPushButton):
        custom_clicked = QtCore.pyqtSignal(str, name='customClicked')
        def mousePressEvent(self, event):
            self.custom_clicked.emit("Clicked!")
    
    class SignalsAndSlots(QtGui.QWidget):
    
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            layout = QtGui.QHBoxLayout(self)
            self.custom_button = CustomButton("Press Me", self)
            self.custom_button.setObjectName('customButton')
            self.label = QtGui.QLabel("Nothing...", parent=self)
            layout.addWidget(self.custom_button)
            layout.addWidget(self.label)
            QtCore.QMetaObject.connectSlotsByName(self)
    
        @QtCore.pyqtSlot(str, name='on_customButton_customClicked')     
        def autoSlot(self, msg):
            self.label.setText(msg)
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        gui = SignalsAndSlots()
        gui.show()
        app.exec_()
    

    But I think you should consider not using the object names. New-style signal connection is way neater. Here is the same application :

    import sys
    from PyQt4 import QtGui, QtCore
    
    class CustomButton(QtGui.QPushButton):
        custom_clicked = QtCore.pyqtSignal(str)
        def mousePressEvent(self, event):
            self.custom_clicked.emit("Clicked!")
    
    class SignalsAndSlots(QtGui.QWidget):
    
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            layout = QtGui.QHBoxLayout(self)
            self.custom_button = CustomButton("Press Me", self)
            self.custom_button.setObjectName('customButton')
            self.label = QtGui.QLabel("Nothing...", parent=self)
            layout.addWidget(self.custom_button)
            layout.addWidget(self.label)
            self.custom_button.custom_clicked.connect(self.on_clicked)
    
        def on_clicked(self, msg):
            self.label.setText(msg)
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        gui = SignalsAndSlots()
        gui.show()
        app.exec_()