Reputation: 555
I'm trying to understand how the signals/slots work within a GUI program. For example, if a slot in the main program gets a signal, does it create another thread to handle the slot?
mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void finished_result(int);
private:
Ui::MainWindow *ui;
QThread* thread;
Worker* worker;
private slots:
void run_click();
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),ui(new Ui::MainWindow){
ui->setupUi(this);
}
MainWindow::~MainWindow(){
delete ui;
}
void MainWindow::run_click(){
thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker,SIGNAL(task_finished(int)),this,SLOT(finished_result(int)));
// all other necessary signal/slot connections
thread->start();
// do more stuff
}
void MainWindow::finished_result(int x){
// do some stuff
}
In a program such as this, say the "do more stuff" take a while to process and the worker finishes the work before run_click()
returns. So run_click()
will be still running when task_finished(int)
is emitted. Will finished_result(int)
start immediately or will it wait for run_click()
to finish? Will finished_result(int)
start in the same thread as run_click()
or in a new thread?
My particular problem is I have an unrelated QWaitCondition
in my "do more stuff" which holds that thread for a while. I want my finished_result(int)
to go ahead without waiting for run_click()
to finish. Any ideas how to proceed? Will I need to move "do more stuff" to another worker in a new thread?
Upvotes: 2
Views: 487
Reputation: 16401
Good answer from Boris (+1)
I would just add for your second question, where you want finished_result() to be handled without waiting for run_click() then you would need to put that into another thread (and connect it all up) if you want it to run "safely".
You may read that Qt does allow you to force the connection to be a "DirectConnection" where the signal is handled as soon as it is received, this is default for signal within the same thread, but to do this accross threads is very dangerous, so don't be tempted by that option!
There might be a third option to pause the current event and find the next item on the event queue.. but I am not sure about that, I thought I read somthing like this a while back but can't find it... maybe someone can answer that part? (I'll take a look see if I can find this).
Upvotes: 1
Reputation: 7788
No, signals never create new threads.
In your case, run_click()
and finished_result(int x)
will be performed in the same thread, and in this order. When the signal task_finished(int)
is emitted from your worker thread, it will be transferred and wait in a queue of your main thread, waiting for run_click()
to finish and hence return to the event loop. Only then finished_result(int x)
will be called.
This is called "Queued Connection" and is the default behaviour when using signals and slots accross different threads. Have a look at Threads and QObjects from the documentation for more info, in particular the section Signals and Slots Across Threads.
Upvotes: 3