im trying to have the scope of the qthread in different object of my project. so i tried to make the thread a singleton . it is a DBUS interface im using as a client.
this is my implemented code . .h
class ClientDBUSThread : public QThread
{
Q_OBJECT
public:
static ClientDBUSThread *getInstance();
void messageReceived(QString );
private:
ClientDBUSThread();
static ClientDBUSThread *instance;
static QMutex instanceMutex;
void run();
signals:
void signalReceivedInDBUS(QString);
public Q_SLOTS:
void mySlot(QString);
void stop();
private:
DemoIf* client ;
QMutex m_mutex;
bool m_stop;
};
and .cpp
#include "ClienDBusThread.h"
#include <QMap>
ClientDBUSThread *ClientDBUSThread::instance(0);
QMutex ClientDBUSThread::instanceMutex;
ClientDBUSThread *ClientDBUSThread::getInstance()
{
if (!instance) {
QMutexLocker instanceMutexLocker(&instanceMutex);
if (!instance) {
instance = new ClientDBUSThread();
}
}
return instance;
}
ClientDBUSThread::ClientDBUSThread()
{
m_stop = false;
client = new DemoIf("com.nokia.Demo", "/", QDBusConnection::sessionBus(), 0);
connect(client, SIGNAL(LateEvent(QString)), this, SLOT(mySlot(QString)));
QDBusConnection cnn= client->connection();
qDebug()<<"is the DBUS gets connected:"<<cnn.isConnected();
const QMap<QString, QVariant> hi;
client->SayHello("HELLO THERE HOW ARE YOU", hi);
client->SayBye();
}
void ClientDBUSThread::run()
{
while (1) {
QMutexLocker locker(&m_mutex);
if (m_stop) break;
}
}
void ClientDBUSThread::stop()
{
QMutexLocker locker(&m_mutex);
m_stop=true;
client->SayBye();
}
void ClientDBUSThread::messageReceived(QString message)
{
const QMap<QString, QVariant> hi;
client->SayHello(message, hi);
}
void ClientDBUSThread::mySlot(QString data)
{
emit signalReceivedInDBUS(data);
}
while declaring the object like
theDBUSThread = ClientDBUSThread::getInstance(); it is fine but while starting the thread
theDBUSThread->start();
the CPU load is exceeding 100% of the PC . im starting the thread only in main class . the rest class im just declaring and using the signals the DBUS receives .
Only your run() loop code gets executed in the thread. How do you expect that code runs anything else without an event loop running the slots when they are triggered?
You should not subclass from QThread in this case.
Instead, derive your class from QObject.
class ClientDBUSThread : public QObject
{
Q_OBJECT
public:
static ClientDBUSThread *getInstance();
void messageReceived(QString );
private:
ClientDBUSThread();
static ClientDBUSThread *instance;
static QThread * thread;
static QMutex instanceMutex;
//void run(); //removed
signals:
void signalReceivedInDBUS(QString);
public Q_SLOTS:
void startup();
void mySlot(QString);
void stop();
private:
DemoIf* client ;
QMutex m_mutex;
bool m_stop;
};
Create a static QThread instance in GetInstance() along with your main class. Then move the latter to the thread:
ClientDBUSThread *ClientDBUSThread::getInstance()
{
if (!instance) {
QMutexLocker instanceMutexLocker(&instanceMutex);
if (!instance) {
//You will need to destroy these somewhere
instance = new ClientDBUSThread();
thread = new QThread();
instance->moveToThread(thread);
connect(thread, SIGNAL(started()), instance, SLOT(startup()));
//the thread is not started yet, you need to thread->start() somewhere
}
}
return instance;
}
Then do your startup jobs not in constructor, but in startup
void ClientDBUSThread::ClientDBUSThread()
{
//I supposed that last argument of DemoIf constructor
//is the pointer to parent. It may be a good idea to parent it with this,
//So I replaced 0 by this
client = new DemoIf("com.nokia.Demo", "/", QDBusConnection::sessionBus(), this);
connect(client, SIGNAL(LateEvent(QString)), this, SLOT(mySlot(QString)));
}
void ClientDBUSThread::startup()
{
m_stop = false;
QDBusConnection cnn= client->connection();
qDebug()<<"is the DBUS gets connected:"<<cnn.isConnected();
const QMap<QString, QVariant> hi;
client->SayHello("HELLO THERE HOW ARE YOU", hi);
client->SayBye();
}