Помогите мне понять использование QThread - PullRequest
0 голосов
/ 06 марта 2011

У меня есть MainWindow w окна и TestThread testThread в качестве члена w.Я знаю это просто, но я не могу запустить метод testThread.foo() в потоке testThread (не в потоке окна).Другими словами: я не понимаю поведение QThread.

Пожалуйста, помогите исправить следующее тестовое приложение.Есть QProgressBar *MainWindow::ui::progressBar и QPushButton *MainWindow::ui::startButton (пиши просто).Я хочу начать (startButton щелчок) TestThread::foo(int* progress), который будет увеличиваться int progress каждую секунду.

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

Я знаю, это просто.Я делаю что-то не так:)

PS Я хочу запустить самый простой (насколько это возможно) пример, чтобы понять поведение QThread.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 06 марта 2011

Критическая проблема заключается в том, чтобы объект, содержащий функцию foo(), принадлежал этому потоку, чтобы вызовы слотов отправлялись из цикла обработки правого потока.

(Обратите внимание, что фактически нет необходимости иметь foo() для объекта TestThread. Вы можете использовать отдельные объекты для функций QThread и WhatEver::foo(). Это может быть и проще, я не точно ..)

IIUC, это то, что вы должны сделать:

  • Используйте QObject :: moveToThread () , чтобы назначить объект, содержащий функцию foo, TestThread (это означает, что Qt::AutoConenction (по умолчанию) вызовы сигнала / слотов будут правильно выполняться в потоке, будучи отправленным из каждого цикла событий каждого потока).

При наличии объекта, "принадлежащего" правому потоку, вызовы слотов будут планироваться в цикле событий этого потока, а не выполняться напрямую.

Надеюсь, это поможет. :)

2 голосов
/ 06 марта 2011

Одно альтернативное решение: если вы просто хотите запустить функцию в другом потоке и не настаиваете на использовании QThread, вы должны проверить QT Concurrent Namespace.

В следующем примере функция foo () будет запущена в отдельном потоке и не будет блокироваться в строке, где вызывается функция. Конечно, существуют механизмы, позволяющие понять, когда функция завершается, чтобы получить результат, дождаться его, контролировать выполнение.

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

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

Надеюсь, это поможет

1 голос
/ 06 марта 2011
...