create qt thread event loop

10,232

Solution 1

why not use qthreadpool, than you make your task class inherits from qrunnable and qobject, this way you can use signals and slots to pass data from one thread to another, is much simpler to implement, and increase performance from not recreating a thread or having one sleeping all the time

class myTask : public QObject, public QRunnable{
Q_OBJECT

protected:
void run(); //where you actually implement what is supposed to do

signals:
void done(int data);//change int to whatever data type you need

}

//moc click example, or use a timer to call this function every x amount of time
void button_click(){
   myTask *task = new myTask();
   task->setAutoDelete(true);
   connect(task,SIGNAL(done(int)),this,SLOT(after_done(int)),Qt::QueuedConnection);
   QThreadPool::globalInstance()->start(task);
}

by default you application gets 1 thread automatically, which you can use to handle the graphic, than use the qthreadpool to process the data/object on demand, you can even set the max amount of threads your application can use to process new request, the others will stay in a queue until one thread is freed

QThreadPool::globalInstance()->setMaxThreadCount(5);

Solution 2

this is a sample code for you :

QThread* thread = new QThread();
Worker* worker = new Worker(3000);
worker->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(start()));
thread->start();`

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(qint32,QObject *parent = 0);
    qint32 myTime;

signals:
    void   workFinished();

public slots:
    void doWork();
    void start();
    private:
    QTimer *timer;
};


#include "worker.h"
#include <QTimer>
#include <QDebug>
Worker::Worker(qint32 t,QObject *parent) :
    QObject(parent)
{
    myTime=t;
}

void Worker::start()
{
    timer = new QTimer();
    timer->start(myTime);
    qDebug()<<QString("start work in time:%1").arg(myTime);
    connect(timer,SIGNAL(timeout()),this,SLOT(doWork()));
}

void Worker::doWork()
{
    qDebug()<<"dowork";
    timer->stop();
    emit workFinished();
}

Debug results :

start work in time:3000

I hope this helps you.

Share:
10,232
Sven Jung
Author by

Sven Jung

Updated on June 12, 2022

Comments

  • Sven Jung
    Sven Jung almost 2 years

    I am using Qt in order to write a GUI application.

    A main thread is responsible for the GUI and creates an QThread in order to do some work with an object.

    class Worker
    {
        void start() {
            QTimer* timer = new Timer();
            connect(timer,SIGNAL(timeout()),this,SLOT(do()));
        }
    
        void do() {
            //do some stuff
            emit finished();
        }
    }
    
    
    
    class GUI
    {
        //do some GUI work then call startWorker();
    
        void startWorker() {
            QThread* thread = new Thread();
            Worker* worker = new Worker();
    
            worker->moveToThread(thread);
    
            connect(thread, SIGNAL(started()), worker, SLOT(start()));
            connect(worker, SIGNAL(finished()), workerthread, SLOT(quit()));
            connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
        }
    }
    

    Now I have several problems:

    1. The timer in my worker class does not work. Maybe it is because the new thread has no event loop, but I have no idea how to create such one. I tried

      connect(workerthread, SIGNAL(started()), workerthread, SLOT(exec()));

      but it does not work either.

    2. When I try to wait on the new thread, the signal is never sent

      class GUI
      {
          void exit() {
              thread->wait();
          }
      }
      

    I think it also is because there is no event loop and because of that no signal is emitted.

    Does anybody have an idea how to solve these problems?