[Qt-interest] Bug? sender() is always NULL when receiver lives in different QThread from emitter

Florian Vichot florian.vichot at diateam.net
Mon Jul 6 16:07:47 CEST 2009


Hello list and trolls,

I've just spend the morning debugging the weirdest bug, and I finally
tracked it down to what it says in the title: when calling
QObject::sender() inside a slot that was called by a signal, the
receiver QObject has to "live" inside the same QThread as the emitter of
the signal, otherwise the value of sender() is always NULL.

I fully understand that using Qt::DirectConnection between objects that
live in different threads is a bad idea, but all I need is
sender()->objectName(), so that seems safe, especially as I have the
certainty that sender() won't have been deleted in the mean time.

And anyway, I'd very much like to be able to shoot myself in the foot if
I feel like it :)

So is it intentional, as some kind of "protection", or is it bug ? From
my point of view, it's definitely a bug, as I need that sender() pointer
in my slot, I can't just move my objects around in QThreads all the time
just to please the metacall mecanism :)

Switched to using QueuedConnection is not really an option, as my object
could have been deleted in the mean time (my app is very multithreaded).

Below is a very stupid example that reproduces that behaviour. If I
uncomment the two lines in main(), sender() becomes NULL when printed.

I'm using Ubuntu 9.04, with Qt 4.5.0.

/****************************************/
// foo.h
#include <QtCore>

class SlotClass : public QObject
{
  Q_OBJECT
  public slots:
    void mySlot()
    {
      qDebug() << sender();
    }
};

class SignalClass : public QObject
{
  Q_OBJECT
  public:
    void emitSignal() {emit mySignal();}

  signals:
    void mySignal();
};

/****************************************/
// main.cpp
#include "foo.h"

int main(int argc, char ** argv)
{
  QCoreApplication app(argc,argv);

  SlotClass slot;
  SignalClass sig;
//  QThread t;
//  slot.moveToThread(&t);

  QObject::connect(&sig,  SIGNAL(mySignal()),
                   &slot,   SLOT(mySlot()),
                   Qt::DirectConnection);

  sig.emitSignal();

  return true;
}
/****************************************/

Thanks,
Florian



More information about the Qt-interest-old mailing list