Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
[SOLVED] Slots from a base class will not be called when subclassing it
Now, starting with Qt/qml I want to use my own threading class, based on
QThread. I've read some articles, threads and blogs about QThread and learned
that it is better not to subclass QThread directly but to implement a class
that will instantiate a QThread object and use the moveToThread() method, what
I finally did.
So far it runs nicely, a thread may be created and started. But, as the following code is just the base implementation I want to subclass it for each thread I am going to use in my application. And then, the problem begins. In the ThreadBase class I have connected a slot (onThreadFinished()) to be called when the QThread finally has stopped working to delete the QThread instance.
But that slot won't be called as soon as I have a derived implementation of the process() method.
To be a bit more precise, here is the complete code:
class ThreadBase : public QObject
ThreadBase(QString qstrObjectName = QString("USER_THREAD"));
void error(QString qstrError);
virtual void process();
virtual void onThreadFinished();
virtual void onError(QString qstrError);
#endif // THREAD_BASE_H
// create thred instance and pass over this worker instance
m_pThread = new QThread;
connect(m_pThread, SIGNAL(started()), this, SLOT(process())); connect(this, SIGNAL(processingFinished()), m_pThread, SLOT(quit())); connect(this, SIGNAL(processingFinished()), m_pThread, SLOT(deleteLater())); connect(m_pThread, SIGNAL(finished()), this, SLOT(onThreadFinished())); m_pThread->start();
qDebug("El Processo says: 'Base process() implementation... even if it's boring, nothing should ever happen here...'");
qDebug() << "El Finito says: 'Thread " + m_pThread->objectName() + " has been shutted down... instance of ThreadBase may be destroyed now'";
void ThreadBase::onError(QString qstrError)
qDebug() << qstrError;
That's for the base implementation. As said before, as long as I do not re-implement the process() method, the onThreadFinished() slot will be called as desired.
Now for the derived class:
class MainLoop : public ThreadBase
//re-implementation of process method to do some stuff... virtual void process();
qDebug("El Processo says: 'running Main Loop...'");
When instatiating a MainLoop object, the processing will run perfectly, but the desired slot is never called.
Now I hope someone here is able to enlighten me, what I have done wrong :)
------------------------ SOLUTION: see last reply: http://qt-project.org/forums/viewreply/172919/
Hi and welcome to devnet,
The problem is that in MainLoop, you don't declare process as a slot so it's a normal function.
On a side note:
Is not really useful, if the allocation of m_pThread fails, your application has exhausted the available memory and will probably get killed by the system.
thanks for your welcome and your fast reply.
I've just tried to as you wrote:
virtual void process();
in the MainLoop.h to declare as a slot but it won't change the behaviour. The slot is still not called.
And, what I found out was: the delete line in the ThreadBase::onThreadFinished() not only seems to be pointless as the Slot
connect(this, SIGNAL(processingFinished()), m_pThread, SLOT(deleteLater()));
will do the job of deleting the instance, it might also be dangerous as you never now if the thread is running, right? So, maybe the processingFinished() slot is just needless and the problem seems to be solved.
But, in that case, how do I make sure all the other slots are called in the right manner?
Did you do a clean rebuild after you add the "protected slots" to MainLoop ?
What do you mean by "right manner" ?
Well, with "the right manner" I meant how to check wether a slot is executed on the signals arrival or not.
But anyway... I am just reading a blog ( http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1 ) I guess, I just need much more knowledge and comprehension about Qt's signal/slot and threading system. Until then, we can stop at that stage of discussion.
Thank you for your assistance. As soon as I found out about my problem, I will share my knowledge here :)
You're welcome !
You can also read the latest QThread "documentation":http://qt-project.org/doc/qt-5/qthread.html all cases are now described
adolby last edited by
The reason ThreadBase::onThreadFinished() isn't getting executed is because you override the method where the ThreadBase::processingFinished() signal is emitted. To remedy this, you could call ThreadBase::process() from MainLoop::process().
The docs answer your question about deleteLater: http://qt-project.org/doc/qt-5/qobject.html#deleteLater
Well... might be a beginners failure XD
As I said, I need much more time until I really get used to the signal/slot mechanism.
Thank you adolby and SGaist for your assistance :)