帮助我了解QThread的用法

时间:2011-03-06 16:34:36

标签: qt qthread

我有MainWindow w个窗口和TestThread testThread作为w的成员。我知道这很简单,但是我无法在testThread.foo()线程中运行testThread方法(不在窗口线程中)。换句话说:我不了解QThread的行为。

请帮助纠正下一个测试应用程序。有QProgressBar *MainWindow::ui::progressBarQPushButton *MainWindow::ui::startButton(简单地写)。我想开始(startButton点击)TestThread::foo(int* progress),每秒增加int progress

主窗口:

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
    }
}

我知道,这很简单。我做错了什么:)

P.S。我想运行最简单(尽可能)的示例来理解QThread行为。

谢谢!

3 个答案:

答案 0 :(得分:2)

关键问题是让包含foo() - 函数的对象归该线程所有,以便从右线程的事件循环调度槽调用。

(请注意,foo()对象上不需要TestThread。您可以为QThreadWhatEver::foo()函数使用单独的对象。也更容易,我不确定..)

IIUC,这就是你要做的事情:

  • 使用QObject::moveToThread()将包含foo-function的对象分配给TestThread(这意味着Qt::AutoConenction(默认)signal / slots调用将在线程间正确运行,从每个线程自己的事件调度环)。

通过右侧线程使对象“拥有”,将在该线程的事件循环上调度slot调用,而不是直接执行。

希望它有所帮助。 :)

答案 1 :(得分:2)

一种替代解决方案:如果您只想在另一个线程中运行一个函数,并且不坚持使用QThread,那么您应该查看QT Concurrent Namespace.

以下示例将在单独的线程中运行函数foo(),并且不会在调用函数的行上阻塞。当然,有一些机制可以理解函数何时结束,获取结果,等待它,以控制执行。

void foo(int &progress) {...}

int progress;
QtConcurrent::run(foo, progress);

希望这有帮助

答案 2 :(得分:1)