[PyQt] [PyQt3] signal sender() and self.name() issues

Hans-Peter Jansen hpj at urpla.net
Sun Sep 16 21:42:03 BST 2007


Hi *,

I stumbled upon some strange effects with signal sender() and self.name() 
properties in PyQt3. I had the impression, the latter is available 
immediately after calling a QObject derived constructor, while the Qt3 
documentation states: 

Returns a pointer to the object that sent the signal, if called in a slot 
activated by a signal; otherwise it returns 0. The pointer is valid only 
during the execution of the slot that calls this function. 
The pointer returned by this function becomes invalid if the sender is 
destroyed, or if the slot is disconnected from the sender's signal. 

Hmm, that doesn't explain the effects I'm suffering from.

Here's code, that tries to exercise these issues:

#!/usr/bin/env python

from qt import *
import sys

class Emitter(QObject):
    def __init__(self, *args):
        QObject.__init__(self, *args)
        self.counter = 0
        self.timer = QTimer(self)
        self.connect(self.timer, SIGNAL("timeout()"), self.trigger)
        self.timer.start(1000)

    def trigger(self):
        self.counter += 1
        self.emit(PYSIGNAL("trigger"), (self.counter,))


class Catcher(QTextEdit):
    def __init__(self, arg, *args):
        self._arg = arg
        QTextEdit.__init__(self, *args)
        self.setTextFormat(QTextEdit.LogText)
        # shouldn't this read: catcher ready [...]
        # while it says: unnamed ready [...]
        self.append("%s ready [%s]" % (self.name(), args))
        self.emitter = Emitter(self, "emitter")
        self.append("%s added" % self.emitter.name())
        self.connect(self.emitter, PYSIGNAL("trigger"), self.catcher)
        self.timer = QTimer(self, "timer")
        self.append("%s added" % self.timer.name())
        self.connect(self.timer, SIGNAL("timeout()"), self.catcher)
        self.timer.start(1000)
        doquit = QAction("Quit", Qt.CTRL+Qt.Key_Q, self, "quit")
        self.connect(doquit, SIGNAL("activated()"), self.close)

    def catcher(self, counter = None):
        # shouldn't sender() return a valid QObject(), where 
        # name() returns the senders name? when this script is executed
        # with an argument, only the timer is resolved correctly, but
        # without args, both signal sender() names are empty.
        sender = self.sender()
        if self._arg:
            sender = sender.name()
        print sender, type(sender)
        if counter != None:
            self.append("%s (%s): counter %s catched" % (
                sender, type(sender), counter))
        else:
            self.append("%s (%s): timer catched" % (
                sender, type(sender)))


a = QApplication(sys.argv)
arg = 0
if len(sys.argv) > 1:
    arg = 1
r = Catcher(arg, None, "catcher")
r.resize(r.sizeHint())
r.show()
a.setMainWidget(r)
a.exec_loop()

The sender resolves to an empty string and empty type inside the text edit:

unnamed ready [(None, 'catcher')]
emitter added
timer added
 (): counter 1 catched
 (): timer catched
 (): counter 2 catched
 (): timer catched
 (): counter 3 catched

while it resolves either to some QTimer objects for both signals (the python 
and Qt one) in the no arg case on the console:

<qt.QTimer object at 0xb679502c> <class 'qt.QTimer'>
<qt.QTimer object at 0xb679505c> <class 'qt.QTimer'>
<qt.QTimer object at 0xb679502c> <class 'qt.QTimer'>
<qt.QTimer object at 0xb679505c> <class 'qt.QTimer'>

In the command line arg case, it's missing the PYSIGNAL name and the types, 
too:

unnamed ready [(None, 'catcher')]
emitter added
timer added
unnamed (): counter 1 catched
timer (): timer catched
unnamed (): counter 2 catched
timer (): timer catched
unnamed (): counter 3 catched
timer (): timer catched

On the console, it shows the expected output (except the "unnamed" issue):

unnamed <type 'str'>
timer <type 'str'>
unnamed <type 'str'>
timer <type 'str'>
unnamed <type 'str'>
timer <type 'str'>

I'm baffled on this one. I'm expecting the some QObjects in both the console 
and the text edit for the first case, while the correct name()s for the 
second..

Distribution: openSUSE 10.2, consisting of:
Python version: 2.5
sip version: 4.2.1
Qt version: 3.3.7
PyQt version: 3.14.1

Could somebody in this kind audience shed some light on these issues, 
please? (or is this simply due to the dusty versions..)

TIA,
  Pete
-------------- next part --------------
A non-text attachment was scrubbed...
Name: emit.py
Type: application/x-python
Size: 2072 bytes
Desc: not available
Url : http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20070916/28829c8c/emit.bin


More information about the PyQt mailing list