9

I have been trying to find a way to update the GUI thread from a Python thread outside of main. The PyQt5 docs on sourceforge have good instructions on how to do this. But I still can't get things to work.

Is there a good way to explain the following output from an interactive session? Shouldn't there be a way to call the emit method on these objects?

>>> from PyQt5.QtCore import QObject, pyqtSignal
>>> obj = QObject()
>>> sig = pyqtSignal()
>>> obj.emit(sig)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'QObject' object has no attribute 'emit'

and

>>> obj.sig.emit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'QObject' object has no attribute 'sig'

and

>>> obj.sig = pyqtSignal()
>>> obj.sig.emit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'emit'
mata
  • 67,110
  • 10
  • 163
  • 162
ADB
  • 1,210
  • 4
  • 15
  • 23
  • 1
    same as here: [PyQt5 in what module is the emit method found?](http://stackoverflow.com/questions/17581506/pyqt5-in-what-module-is-the-emit-method-found) - only __bound__ signals have an `emit` method. (`obj.sig = pyqtSignal()` is still an unbound signal) – mata Jul 12 '13 at 22:44
  • @mata: Yes, I was taking these examples from the PyQt5 docs at sourceforge. As you [pointed out](http://stackoverflow.com/questions/17581506/pyfqt5-in-what-module-is-the-emit-method-found), the emit method is for a bound signal, ie it is a member of a class that inherits from QObject. I didn't realize that I wasn't doing that in the interactive session pasted above. – ADB Jul 14 '13 at 19:13
  • @ mata: Just curious, what would be the utility of **obj.sig = pyqtSignal()**, as in the third example above? – ADB Jul 14 '13 at 19:18
  • `obj.sig = pyqtSignal()` assigns an unbound signal to an object instance - which doesn't make much sense. Signals need to be declared on a class, they're then bound when they're looked up on the instance - they're [descriptors](http://docs.python.org/3/reference/datamodel.html#implementing-descriptors) in PyQt and descriptors only work as such when declared on a class. – mata Jul 14 '13 at 19:55
  • Thanks this is going to be helpful for the project that I'm working on. Thank you for taking the time to answer my questions. – ADB Jul 15 '13 at 03:32

1 Answers1

32

Following words and codes are in PyQt5 docs.

New signals should only be defined in sub-classes of QObject.They must be part of the class definition and cannot be dynamically added as class attributes after the class has been defined.

from PyQt5.QtCore import QObject, pyqtSignal

class Foo(QObject):

    # Define a new signal called 'trigger' that has no arguments.
    trigger = pyqtSignal()

    def connect_and_emit_trigger(self):
        # Connect the trigger signal to a slot.
        self.trigger.connect(self.handle_trigger)

        # Emit the signal.
        self.trigger.emit()

    def handle_trigger(self):
        # Show that the slot has been called.

        print "trigger signal received"
Jacky
  • 514
  • 6
  • 17
  • Wow, more than a year later! Answer accepted (even though question was cleared in the comments above). – ADB Oct 22 '14 at 05:09
  • 1
    Also bear in mind that if you implement `__init__` on your subclass of `QObject` you also have to call the superclass `__init__` – mike rodent Nov 16 '20 at 22:09