c++multithreadingqt5qthread

creating new thread using Qthread-Qt5


I am trying to create a new thread gpsthread which should run in the back ground, and store the value.

class gpsthread: public QThread{
    Q_OBJECT
private:nrega_status_t status2;

public: 
explicit gpsthread(QObject *parent = 0):QThread(parent) {
    // QTimer *t = new QTimer(this);
    // connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
    // t->start(10000);
 }
 void run(){
    qDebug()<<"inside gps thread\n";
    QTimer *t = new QTimer(this);
     connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
     t->start(10000);
    }

public slots:void processgps(){
    int status2;
    status2=gps_management();
}
};

My main class is quickview.

int main(int argc, char *argv[])
{

QString file = "qml/main.qml";
QApplication app(argc, argv);
TranslationTest myObj;
QuickView view;
subthread object;
gpsthread obj;
gprsthread gprs;
view.rootContext()->setContextProperty("rootItem", (QObject *)&myObj);

    obj.start();
//from subthread
QObject::connect(&object, SIGNAL(batterytoqml(QVariant,QVariant)),item, SLOT(frombattery(QVariant,QVariant)));
QObject::connect(&gprs, SIGNAL(gprstoqml(QVariant)),item, SLOT(fromgprs(QVariant)));
return app.exec();

}

I have tried this as well

class gpsthread: public QThread{
    Q_OBJECT
private:nrega_status_t status2;

public:QTimer* t; 
explicit gpsthread(QObject *parent = 0):QThread(parent) {
    // QTimer *t = new QTimer(this);
    // connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
    // t->start(10000);
 }
 void run(){
    qDebug()<<"inside gps thread\n";
    t = new QTimer(this);
     connect(t, SIGNAL(timeout()), this, SLOT(processgps()));
     t->start(10000);
exec();    
}

public slots:void processgps(){
    int status2;
    status2=gps_management();
}
};

But it is giving error saying

 QObject: Cannot create children for a parent that is in a different thread

If I create object in constructor then also it will give the same error because the object will be created in the main thread. How to resolve this?


Solution

  • Inheriting from QThread is not the recommended usage. QThread is a complete class that runs an event loop, which is generally what you need. The documentation recommends using a worker object that inherits from QObject and does work in a slot. The worker is moved into a QThread. When a connected signal is sent, the slot will run in the correct thread.

    class gpsworker: public QObject
    {
    Q_OBJECT
    public:
        explicit gpsworker(QObject *parent = 0):
        QObject(parent)
        {}
    
    public slots:
        void processgps() {
            qDebug() << "processgps()" << QThread::currentThreadId();
        }
    }
    
    void OwnerClass::startWorker() {
        QTimer *timer = new QTimer(this);
        QThread *thread = new QThread(this);
        this->worker = new gpsworker();
        this->worker->moveToThread(thread);
        connect(timer, SIGNAL(timeout()), this->worker, SLOT(processgps()) );
        connect(thread, SIGNAL(finished()), this->worker, SLOT(deleteLater()) );
        thread->start();
        timer->start();
    }
    

    If you want the timer to live in the other thread as well, QTimer::start is a slot.