gui to thread and vice versa.



  • i would like to update the worker thread from the main gui and also send information from the thread to the gui. I have code that works. but when i click the spin box consecutively. i miss some clicks. i was wondering if somebody can tell me what i am doing wrong.

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "thread.h"
    #include "datathread.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    signals:
        void UpdateThreadValue(int arg1);
    
    private slots:
        void on_spinBox_valueChanged(int arg1);
        void updatelabelvalue(int arg1);
    
    private:
        Ui::MainWindow *ui;
        QThread    *T1;
        DataThread *worker;
    };
    
    #endif // MAINWINDOW_H
    
    #include "datathread.h"
    
    DataThread::DataThread(QObject *parent) : QObject(parent)
    {
        IsRunning = true;
        value = 0;
        UiModified = false;
    }
    
    void DataThread::process()
    {
        while(IsRunning)
        {
            if(UiModified)
            {
                qDebug() << value;
                emit changelabel(value);
            }
    
            UiModified  = false;
            QThread::msleep(250);
        }
    
        emit finished();
    }
    
    void DataThread::SetValue(int val)
    {
        QMutexLocker locker(&Mutex);
        value = val;
        UiModified = true;
    }
    
    int DataThread::getValue() const
    {
        return value;
    }
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        T1 = new QThread();
        worker = new DataThread();
    
        worker->moveToThread(T1);
    
       // this does not work
       // connect(this,SIGNAL(UpdateThreadValue(int)),worker,SLOT(SetValue(int)));
       
         connect(worker,SIGNAL(changelabel(int)),this,SLOT(updatelabelvalue(int)));
        
        // this works 
        //connect(this,SIGNAL(UpdateThreadValue(int)),worker,SLOT(SetValue(int)), Qt::DirectConnection);
        
        connect(T1, SIGNAL(started()), worker, SLOT(process()));
        connect(worker, SIGNAL(finished()), T1,SLOT(quit()));
        connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
        connect(T1,SIGNAL(finished()), T1,SLOT(deleteLater()));
        T1->start();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_spinBox_valueChanged(int arg1)
    {
        emit UpdateThreadValue(arg1);
    
    }
    
    void MainWindow::updatelabelvalue(int arg1)
    {
        ui->label->setText(QString::number(arg1));
    }

  • Moderators

    Don't use DirectConnection across threads. It throwas thread-safety out of the window and puts your program in undefined behavior land, so it might seem to work on your machine and simply crash on another or under some other cpu load conditions etc. Just don't do it.

    To have a slot fired in another thread you need to have a Qt's event loop running there. Your while(IsRunning) loop is blocking and does not process any Qt's event and so no slots will be called until you exit process() (which is not gonna happen in your current setup).

    To fix this don't create a loop of your own in that worker thread. When you call T1->start() Qt already creates an event loop there. Don't call blocking process when it starts. When you need to do some work simply emit a signal with the data as a parameter and connect it to a slot of an object in that thread. It will get fired and any synchronization needed will be done for you so you won't even need that mutex.



  • Thanks! its working now.



  • Also...
    Take a look to this library, so nice for sync jobs
    https://github.com/mhogomchungu/tasks


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.