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)); }
-
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 exitprocess()
(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 blockingprocess
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. -
Also...
Take a look to this library, so nice for sync jobs
https://github.com/mhogomchungu/tasks