[SOLVED] Slots from a base class will not be called when subclassing it
-
wrote on 19 Apr 2014, 20:07 last edited by
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:
ThreadBase.h
@
#if(!defined(THREAD_BASE_H))
#define THREAD_BASE_H#include "ThreadWorker.h"
#include <QObject>class QThread;
class ThreadBase : public QObject
{
Q_OBJECTpublic:
ThreadBase(QString qstrObjectName = QString("USER_THREAD"));
virtual ~ThreadBase();signals:
void processingFinished();
void error(QString qstrError);protected slots:
virtual void process();
virtual void onThreadFinished();
virtual void onError(QString qstrError);protected:
QThread* m_pThread;private:
};#endif // THREAD_BASE_H
@ThreadBase.cpp
@#include <QThread>
#include <QDebug>#include "ThreadBase.h"
ThreadBase::ThreadBase(QString qstrObjectName)
//: ThreadWorker()
: QObject()
{
// create thred instance and pass over this worker instance
m_pThread = new QThread;if(m_pThread)
{
m_pThread->setObjectName(qstrObjectName);
this->moveToThread(m_pThread);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();
}
}ThreadBase::~ThreadBase()
{
delete m_pThread;
}void ThreadBase::process()
{
qDebug("El Processo says: 'Base process() implementation... even if it's boring, nothing should ever happen here...'");
emit processingFinished();
}void ThreadBase::onThreadFinished()
{
qDebug() << "El Finito says: 'Thread " + m_pThread->objectName() + " has been shutted down... instance of ThreadBase may be destroyed now'";
delete m_pThread;
}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:
MainLoop.h
@
#if(!defined(MAIN_LOOP__H))
#define MAIN_LOOP__H#include "thread/ThreadBase.h"
class MainLoop : public ThreadBase
{
Q_OBJECTpublic:
MainLoop();
virtual ~MainLoop();//re-implementation of process method to do some stuff... virtual void process();
private:
};#endif //MAIN_LOOP__H
@MainLoop.cpp
@
#include "MainLoop.h"#include <QDebug>
MainLoop::MainLoop()
: ThreadBase("MAIN_LOOP")
{
}MainLoop::~MainLoop()
{
}void MainLoop::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 :)
Best wishes,
Coastcrawler------------------------ 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:
@
if(m_pThread)
{@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.
-
wrote on 20 Apr 2014, 08:13 last edited by
Hi SGaist,
thanks for your welcome and your fast reply.
I've just tried to as you wrote:
@
protected slots:
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?
Best Regards,
Coast -
Did you do a clean rebuild after you add the "protected slots" to MainLoop ?
What do you mean by "right manner" ?
-
wrote on 21 Apr 2014, 12:14 last edited by
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
-
wrote on 21 Apr 2014, 21:36 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
-
wrote on 22 Apr 2014, 16:44 last edited by
omfg... yes...
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 :)
8/8