Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt - updating main window with second thread

Tags:

i have an multithreaded qt application. when i am doing some processes in mainwindow.cpp, at the same time, i want to update mainwindow.ui from other thread.

i have mythread.h

#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> #include "mainwindow.h"  class mythread : public QThread {     public:         void run();         mythread( MainWindow* ana );      MainWindow* ana; private:  };  #endif // MYTHREAD_H 

mythread.cpp

mythread::mythread(MainWindow* a) {     cout << "thread created" << endl;         ana = a; }  void mythread::run() {     QPixmap i1 (":/notes/pic/4mdodiyez.jpg");     QLabel *label = new QLabel();     label->setPixmap(i1);     ana->ui->horizontalLayout_4->addWidget(label);   } 

but the problem is that, i cannot reach the ana->ui->horizontalLayout_4->addWidget(label);

how can i do that?

like image 249
abby Avatar asked May 11 '13 20:05

abby


2 Answers

but the problem is that, i cannot reach the ana->ui->horizontalLayout_4->addWidget(label);

Put your UI modifications in a slot in your main window, and connect a thread signal to that slot, chances are it will work. I think only the main thread has access to the UI in Qt. Thus if you want GUI functionality, it must be there, and can be only signaled from other threads.

OK, here is a simple example. BTW, your scenario doesn't really require to extend QThread - so you are better off not doing it, unless you really have to. That is why in this example I will use a normal QThread with a QObject based worker instead, but the concept is the same if you subclass QThread:

The main UI:

class MainUI : public QWidget {     Q_OBJECT  public:     explicit MainUI(QWidget *parent = 0): QWidget(parent) {         layout = new QHBoxLayout(this);         setLayout(layout);         QThread *thread = new QThread(this);         GUIUpdater *updater = new GUIUpdater();         updater->moveToThread(thread);         connect(updater, SIGNAL(requestNewLabel(QString)), this, SLOT(createLabel(QString)));         connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));          updater->newLabel("h:/test.png");     }  public slots:     void createLabel(const QString &imgSource) {         QPixmap i1(imgSource);         QLabel *label = new QLabel(this);         label->setPixmap(i1);         layout->addWidget(label);     }  private:     QHBoxLayout *layout; }; 

... and the worker object:

class GUIUpdater : public QObject {     Q_OBJECT  public:     explicit GUIUpdater(QObject *parent = 0) : QObject(parent) {}         void newLabel(const QString &image) { emit requestNewLabel(image); }  signals:         void requestNewLabel(const QString &); }; 

The worker object is created and moved to another thread, then connected to the slot that creates the labels, then its newLabel method is invoked, which is just a wrapper to emit the requestNewLabel signal and pass the path to the image. The signal is then passed from the worker object/thread to the main UI slot along with the image path parameter and a new label is added to the layout.

Since the worker object is created without parent in order to be able to move it to another thread, we also connect the thread destroyed signal to the worker deleteLater() slot.

like image 179
dtech Avatar answered Oct 01 '22 15:10

dtech


First and foremost, "you're doing it wrong". Normally you want to create a class derived from a QObject and move that class to a new thread object instead of deriving your class from a Qthread

Now to get onto the specifics of your question, you're not able to directly modify the ui elements of your main GUI thread from a separate thread. You have to connect a signal from your 2nd thread to a slot in your main thread. You can pass any data that you need through this signal/slot connection but you're unable to directly modify the ui element (which in all honestly you probably do not want to if you intend to keep the frontend of your app separate from the backend). Checkout Qt's signal and slot documentation for a whole lot more information

like image 32
g19fanatic Avatar answered Oct 01 '22 15:10

g19fanatic