Qt How to pass data from a GUI to another thread : <p>I have an application that can start pause and cancel the thread.
i would like to pass data from the main gui to the thread. 
in this example i have a spinbox. 
i wish to reset the counter in the worker thread everytime i change the spin box. </p>

<p>for some reason i can't seem to update the counter variable in the worker thread. 
what am i missing in my program?</p>

<p>MAINWINDOW.h</p>

<pre><code>#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include &lt;QMainWindow&gt;
    #include &lt;QThread&gt;

    #include "worker.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
        Q_OBJECT

    signals:
        void updatecounter(int val);

    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();

    private slots:


        void on_Time_valueChanged(const QString &amp;arg1);

        void on_Start_clicked();

        void on_Stop_clicked();

        void on_Pause_clicked();

    private:
        Ui::MainWindow *ui;
        QThread        *m_Thread;
        Worker         *m_Worker;

    };

    #endif // MAINWINDOW_H
</code></pre>

<p>WORKER.h</p>

<pre><code>#ifndef WORKER_H
#define WORKER_H

#include &lt;QObject&gt;
#include &lt;QMutex&gt;
#include &lt;QThread&gt;
#include &lt;QDebug&gt;
#include &lt;QEventLoop&gt;
#include &lt;QAbstractEventDispatcher&gt;

class Worker : public QObject
{
    Q_OBJECT

public:
    Worker();
    ~Worker();

public slots:
    void process();

signals:
    void started();
    void finished();

   public slots:

       void updatecounter(int val)
       {
           counter = val;
       }

       void pause()
       {
           auto const dispatcher = QThread::currentThread()-&gt;eventDispatcher();

           if (!dispatcher)
           {
               qCritical() &lt;&lt; "thread with no dispatcher";
               return;
           }

           if (state != RUNNING)
               return;

           state = PAUSED;
           qDebug() &lt;&lt; this;
           qDebug() &lt;&lt; "paused";

           do
           {
               dispatcher-&gt;processEvents(QEventLoop::WaitForMoreEvents);
           } while (state == PAUSED);
       }

       void resume()
       {
           if (state == PAUSED)
           {
               state = RUNNING;
               qDebug() &lt;&lt; this;
               qDebug() &lt;&lt; "resumed";

               updatecounter(0);
           }
       }

       void cancel()
       {
           if (state != IDLE)
           {
               state = IDLE;
               qDebug() &lt;&lt; this;
               qDebug() &lt;&lt; "cancelled";
           }
       }

   protected:

       enum State { IDLE, RUNNING, PAUSED };
       State state = IDLE;
       int counter = 0;
       bool isCancelled()
       {
           auto const dispatcher = QThread::currentThread()-&gt;eventDispatcher();

           if (!dispatcher)
           {
               qCritical() &lt;&lt; "thread with no dispatcher";
               return false;
           }

           dispatcher-&gt;processEvents(QEventLoop::AllEvents);

           return state == IDLE;
       }
};

#endif // WORKER_H
</code></pre>

<p>MAINWINDOW.cpp</p>

<pre><code>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include &lt;QDebug&gt;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui-&gt;setupUi(this);

    qDebug() &lt;&lt; "main thread";

    m_Thread = new QThread();

    ui-&gt;Start-&gt;setEnabled(true);
    ui-&gt;Pause-&gt;setEnabled(false);
    ui-&gt;Stop-&gt;setEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_Time_valueChanged(const QString &amp;arg1)
{
    emit updatecounter(arg1.toInt());


    //auto const m = m_Worker-&gt;metaObject();
    //m-&gt;invokeMethod(m_Worker, "updatecounter",Qt::QueuedConnection,Q_ARG(int,arg1.toInt()));
}

void MainWindow::on_Start_clicked()
{
    if(!m_Thread-&gt;isRunning())
    {
        m_Thread = new QThread();
        m_Worker = new Worker();
        m_Worker-&gt;moveToThread(m_Thread);

        connect(m_Thread, &amp;QThread::started, m_Worker, &amp;Worker::process);
        connect(this,&amp;MainWindow::updatecounter, m_Worker, &amp;Worker::updatecounter, Qt::QueuedConnection);
        connect(m_Worker, &amp;Worker::finished, m_Thread, &amp;QThread::quit);
        m_Thread-&gt;start();

    }
    else
    {
        auto const m = m_Worker-&gt;metaObject();
        m-&gt;invokeMethod(m_Worker, "resume");
    }

    ui-&gt;Start-&gt;setEnabled(false);
    ui-&gt;Pause-&gt;setEnabled(true);
    ui-&gt;Stop-&gt;setEnabled(true);
}

void MainWindow::on_Stop_clicked()
{
    auto const m = m_Worker-&gt;metaObject();
    m-&gt;invokeMethod(m_Worker, "cancel");
    ui-&gt;Start-&gt;setEnabled(true);
    ui-&gt;Pause-&gt;setEnabled(false);
    ui-&gt;Stop-&gt;setEnabled(false);

}

void MainWindow::on_Pause_clicked()
{
    auto const m = m_Worker-&gt;metaObject();
    m-&gt;invokeMethod(m_Worker, "pause");
    ui-&gt;Start-&gt;setEnabled(true);
    ui-&gt;Pause-&gt;setEnabled(false);
    ui-&gt;Stop-&gt;setEnabled(true);
}
</code></pre>

<p>WORKER.cpp</p>

<pre><code>#include "worker.h"

#include &lt;QDebug&gt;
#include &lt;QThread&gt;
#include &lt;QTimer&gt;

Worker::Worker()
{
    qDebug() &lt;&lt; this &lt;&lt; " worker thread started";
}

Worker::~Worker()
{
    qDebug() &lt;&lt; "worker thread finished";
}

void Worker::process()
{
    if (state == PAUSED)
               // treat as resume
               state = RUNNING;

           if (state == RUNNING)
               return;

           state = RUNNING;
           qDebug() &lt;&lt; "started";
           emit started();

           // This loop simulates the actual work
           for (auto i = counter;  state == RUNNING;  ++i)
           {
               QThread::msleep(100);
               if (isCancelled())
               {
                   break;
               }

               qDebug() &lt;&lt; i;
           }

           qDebug() &lt;&lt; this;
           qDebug() &lt;&lt; "finished";
           emit finished();
}
</code></pre>
