0

我有MainWindow w窗户,并且TestThread testThreadw. 我知道这很简单,但我不能testThread.foo()在线程中运行该方法testThread(而不是在窗口线程中)。换句话说:我不理解 QThread 的行为。

请帮助更正下一个测试应用程序。有一个QProgressBar *MainWindow::ui::progressBarand QPushButton *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
}

测试线程:

void TestThread::foo(int *progress) // this is a TestThread SLOT
{
    for (unsigned i = 0; i < 5; ++i) {
        sleep(1);
        ++*progress; // increment MainWindow::progress
    }
}

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

PS我想运行最简单(尽可能)的示例来了解QThread行为。

谢谢!

4

3 回答 3

2

关键问题是让包含foo()-function 的对象归该线程所有,以便从正确线程的事件循环中分派插槽调用。

(请注意,实际上不需要foo()TestThread对象上。您可以将单独的对象用于QThreadWhatEver::foo()功能。它也可能更容易,我不确定..)

IIUC,这是你必须做的:

  • 使用QObject::moveToThread()将包含 foo 函数的对象分配给 TestThread (这意味着Qt::AutoConenction(默认)信号/插槽调用将跨线程正确运行,从每个线程自己的事件循环中分派)。

通过让正确的线程“拥有”对象,槽调用将被安排在该线程的事件循环上,而不是直接执行。

希望能帮助到你。:)

于 2011-03-06T17:45:25.097 回答
2

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

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

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

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

希望这可以帮助

于 2011-03-06T17:57:39.570 回答
1

请参阅QThread::startQThread::run

于 2011-03-06T16:58:37.943 回答