Subhamoy S.
Subhamoy S.

Reputation: 6764

Signal-Slot Connection between Creator and Created Class

I have a question.

I have two classes, A and B. A creates object of type B, and also emits signals like this:

QtCore.QObject.emit(QtCore.SIGNAL('mySignal'), "Hello World")

B can see methods in A as A passed 'self' as an argument to the constructor while creating B, as described here.

Now, I want to write a slot in B for that signal emitted in A like this:

self.connect(self._creator, QtCore.SIGNAL('mySignal'), mySlot)

Here I would like to mention that both A and B inherit from QtCore.QObject. The method mySlot is just supposed to print the value it receives as the argument from the signal.

When I run it, I get this error:

QObject.emit(SIGNAL(), ...): first argument of unbound method must have type 'QObject'

In the init() of both the classes, I have added this:

QtCore.QObject.__init__(self)

Without adding this, I get the error:

RuntimeError: underlying C/C++ object has been deleted

I am not experienced in Qt. I do not understand what is going wrong. Please help.

Upvotes: 0

Views: 3042

Answers (1)

reclosedev
reclosedev

Reputation: 9522

first argument of unbound method must have type 'QObject'

As error says, you need to pass reference to A for QtCore.QObject.emit or call it with instance method:

QtCore.QObject.emit(self, QtCore.SIGNAL('mySignal'), "Hello World")

Or

self.emit(QtCore.SIGNAL('mySignal'), "Hello World")

Fully working example (if I understood you right):

from PyQt4 import QtCore

class A(QtCore.QObject):
    mySignal = QtCore.SIGNAL('mySignal(QString)')
    def __init__(self):
        QtCore.QObject.__init__(self)

    def create_b(self):
        return B(self)

    def some_action(self):
        QtCore.QObject.emit(self, QtCore.SIGNAL('mySignal'), "Hello World")
        # this will work too
        self.emit(QtCore.SIGNAL('mySignal'), "Hello World")

class B(QtCore.QObject):
    def __init__(self, creator):
        QtCore.QObject.__init__(self)
        self._creator = creator
        self.connect(self._creator, QtCore.SIGNAL('mySignal'), self.mySlot)

    def mySlot(self, str):
        print str

a = A()
b = a.create_b()
a.some_action()

Even better solution, is to use New-style Signals and Slots

Here is example for you case:

from PyQt4 import QtCore

class A(QtCore.QObject):
    mySignal = QtCore.pyqtSignal(str)
    def __init__(self):
        QtCore.QObject.__init__(self)

    def create_b(self):
        return B(self)

    def some_action(self):
        self.mySignal.emit("Hello World")

class B(QtCore.QObject):
    def __init__(self, creator):
        QtCore.QObject.__init__(self)
        self._creator = creator
        self._creator.mySignal.connect(self.mySlot)

    def mySlot(self, str):
        print str

a = A()
b = a.create_b()
a.some_action()

Upvotes: 1

Related Questions