Reputation: 2164
I have the MainWindow w
windows and TestThread testThread
as a member of w
. I know it i simple, but I cannot run the testThread.foo()
method in testThread
thread (not in window thread). In another words: I don't understand the QThread behavior.
Please help correct the next test application. There is a QProgressBar *MainWindow::ui::progressBar
and QPushButton *MainWindow::ui::startButton
(write simply). I want to start (by startButton
click) TestThread::foo(int* progress)
which will increment int progress
each second.
MainWindow:
MainWindow::MainWindow(QWidget *parent) : // ...
{
// ...
ui->progressBar->setRange(0, 5);
progress = 0; // int MainWindow::progress
this->connect(ui->startButton, SIGNAL(clicked()), SLOT(startFoo()));
connect(this, SIGNAL(startFooSignal(int*)), &testThread, SLOT(foo(int*)));
// TestThread MainWindow::testThread
testThread.start();
}
// ...
void MainWindow::timerEvent(QTimerEvent *event)
{
ui->progressBar->setValue(progress);
}
void MainWindow::startFoo() // this is a MainWindow SLOT
{
startTimer(100);
emit startFooSignal(&progress);
// startFooSignal(int*) is a MainWindows SIGNAL
}
TestThread:
void TestThread::foo(int *progress) // this is a TestThread SLOT
{
for (unsigned i = 0; i < 5; ++i) {
sleep(1);
++*progress; // increment MainWindow::progress
}
}
I know, this is simple. I am doing something wrong :)
P.S. I want to run the simpliest (as possible) example to understand the QThread
behavior.
Thanks!
Upvotes: 0
Views: 1365
Reputation: 25690
The critical issue is to have the object containing the foo()
-function be owned by that thread, so that slot calls are dispatched from the right thread's event-loop.
(Note that there's no need to actually have foo()
on the TestThread
object. You can use separate objects for QThread
and WhatEver::foo()
function. It might be easier too, I'm not sure..)
IIUC, this is what you have to do:
Qt::AutoConenction
(the default) signal/slots calls will run correctly across thread, being dispatched from each thread's own event loop). By having the object "owned" by the right thread, slots calls will be scheduled on that thread's event loop, rather than executed directly.
Hope it helps. :)
Upvotes: 2
Reputation: 3412
One alternative solution: If you just want to run a function in another thread, and don't insist using QThread, you should check out the QT Concurrent Namespace.
The following example will run the function foo() in separate thread and will not block on the line where calling the function. Of course there are mechanisms to understand when a function ends, to get a result, to wait for it, to control execution.
void foo(int &progress) {...}
int progress;
QtConcurrent::run(foo, progress);
Hope this helps
Upvotes: 2