6

Can someone explain to me why is the overridden method is not being called in base class slot, instead I have a base version of method:

class ThreadsDispatcher : public QObject
{
   Q_OBJECT
   public:
      explicit ThreadsDispatcher(QObject *parent = 0);
      virtual ~ThreadsDispatcher();
      virtual void OnThreadFinished(IThreadable *pWorker);

   public slots:
      void slotThreadFinished(IThreadable *pWorker);
};

void ThreadsDispatcher::slotThreadFinished(IThreadable *pWorker)
{
   OnThreadFinished(pWorker);
}

void ThreadsDispatcher::OnThreadFinished(IThreadable *pWorker)
{
   qDebug << "Base method, class" << this->metaObject()->className();
}

A subclass:

class CommandsQueueDispatcher : public ThreadsDispatcher
{
    Q_OBJECT
    public:
       explicit CommandsQueueDispatcher(CommandFactory* baseFactory, QObject *parent = 0);
       ~CommandsQueueDispatcher();
       void OnThreadFinished(IThreadable *pWorker);
};

 void CommandsQueueDispatcher::OnThreadFinished(IThreadable *pWorker)
 {
    qDebug << "Subclass method, class" << this->metaObject()->className();
 }

After call OnThreadFinished in slot I get:

Base method, class ThreadsDispatcher

If I call method OnThreadFinished from another method, I get normal:

Subclass method, class CommandsQueueDispatcher

I have tried to connect in base class and subclass, but there no changes:

connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), this, SLOT(slotThreadFinished(IThreadable*)));

But if I connect from another class, i.e. neither subclass, nor base class:

    connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), pWorker, SLOT(slotThreadFinished(IThreadable*)));

where I need to replace this with the variable ptr, I get a normal result.

Function where I connect:

bool ThreadsDispatcher::AddThread(IThreadable* pThreadWorker)
{
   connect(pThreadWorker, SIGNAL(sigFinished(IThreadable*)), this, SLOT(slotThreadFinished(IThreadable*)));
}

I don't instantiate ThreadsDispatcher directly. I create the CommandsQueueDispatcher's object non-static.

László Papp
  • 51,870
  • 39
  • 111
  • 135
  • Looks strange. Try re-running qmake manually. Also, if you are using shadow build (which IMO is a good idea, and suggested by Qt Creator by default), make sure you haven't accidentally done build in source dir too. – hyde Sep 10 '13 at 05:27
  • I check this on two different computers under qt creator and visual studio 2012 - no effects. It seems that If I use this, then I have not accsess to virtual mebmber's table – Anton Cherepanov Sep 10 '13 at 05:29
  • Can you also show the code where you make signal connection to the slot? Which function implementation will be called depends on the static type of the object. – vahancho Sep 10 '13 at 07:07
  • Is it possible that `OnThreadFinished` is invoked BEFORE construction of object was finished (before `CommandsQueueDispatcher` constructor returns)? If yes then most probably this is your problem http://stackoverflow.com/a/496450/1387438. – Marek R Sep 10 '13 at 09:06
  • No. I check breakpoints. Both contructors returns, then calling OnThreadFinished. Additionally, If I move call OnThreadFinished from slot to another method(simple C++ method), I work perfectly. It is signal/slot's qt system...but why... – Anton Cherepanov Sep 11 '13 at 03:34
  • Where is `AddThread()` called from? Also try adding `qDebug() << this->metaObject()->className();` in `AddThread()` and in the slot. `metaObject()` is virtual so it should tell you the dynamic type. – Oktalist Sep 14 '13 at 13:42

1 Answers1

0

A troubleshooting suggestion (too long for a comment):

Try changing the slot to be like this:

void ThreadsDispatcher::OnThreadFinished(IThreadable *pWorker)
{
   qDebug << "Base method, class" << this->metaObject()->className();
}

And same for derived class. See what is output.

If output is "correct" in the sense that called virtual method is consistent with the class name, then I suspect you somehow do have a base class object, instead of derived class object.

If there's output mismatch, base class virtual method does the print but reports derived class name, then I'd look for any funny compiler flags, and try to create a SSCCE with a fresh project, then perhaps ask again here and/or file a bug report to Qt.

A link for starting to read about this in Qt docs.


A seconds step in troubleshooting: change the base class to be abstract, by making this method abstoract in base class:

  virtual void OnThreadFinished(IThreadable *pWorker) = 0;

...and then remove the method definiton. Now compiler should tell you where you try to create an instance of base class.


One more suggestion: the Qt build basics, listed for example in this answer. In particular, make sure QObject subclasses are defined in .h files, which are listed in .pro file HEADERS list.

Community
  • 1
  • 1
hyde
  • 60,639
  • 21
  • 115
  • 176