Qt предоставляет класс QThread для создания многопоточных приложений. К сожалению, существует некоторая путаница относительно того, как нужно использовать QThread. Данный пост рассказывает о основе, заложенной в класс QThread, а также описывает то, как Вы должны использовать Q-потоки в Ваших приложениях.
Не создавайте подклассов QThread!
Большая часть путаницы происходит из-за того, что QThread используется как абстракатный класс. Такуим образом, единсветнный путь использования Qthread - это создание его подкласса и переопределение метода run(). И это действительно было так, до версии Qt 4.4, начиная с которой метод QThread::run() получил реализацию по умолчанию, следовательно необходимость в создание потомков класса QThread отпала. Главной причиной этому послужил тот факт, что создание потомков класса QThread может препятствовать использованию слотов подклассом.
Единственная причина, по которой, Вам по-прежнему может понадобиться создавать потомки класса QThread - это создание своего собственного цикла приложения(application run-loop).
Используйте moveToThread() и "рабочий" класс, подкласс QObject.
Далее описано, как Вы должны реализовать многопоточную операцию используя класс QThread.
Для начала, создайте "рабочий" класс, который унаследован от класса QObject.
Этот класс должен определять следующие сигналы и слоты:
Заметка является переводом с форума поддержки разработчиков Blackberry.
Не создавайте подклассов QThread!
Большая часть путаницы происходит из-за того, что QThread используется как абстракатный класс. Такуим образом, единсветнный путь использования Qthread - это создание его подкласса и переопределение метода run(). И это действительно было так, до версии Qt 4.4, начиная с которой метод QThread::run() получил реализацию по умолчанию, следовательно необходимость в создание потомков класса QThread отпала. Главной причиной этому послужил тот факт, что создание потомков класса QThread может препятствовать использованию слотов подклассом.
Единственная причина, по которой, Вам по-прежнему может понадобиться создавать потомки класса QThread - это создание своего собственного цикла приложения(application run-loop).
Используйте moveToThread() и "рабочий" класс, подкласс QObject.
Далее описано, как Вы должны реализовать многопоточную операцию используя класс QThread.
Для начала, создайте "рабочий" класс, который унаследован от класса QObject.
Этот класс должен определять следующие сигналы и слоты:
- Слот, в котором происходит вся основная работа.
- Сигнал, который информирует вызывающий код о завершении работы.
- * Опционально, сигнал, который информирует вызывающий код в случае возникновения ошибок.
"Рабочий" класс может выглядеть так:
class Worker : public QObject { Q_OBJECT public: Worker(); virtual ~Worker(); public slots: void process(); signals: void finished(); void error(QString err); };
Далее, используйте QThread в связке с Вашим "рабочим" классом, для выполнения многопоточной работы:
// Создание потока QThread* thread = new QThread; Worker* worker = new Worker(); // Передаем права владения "рабочим" классом, классу QThread. worker->moveToThread(thread); // Связываем сигнал об ошибки со слотом обработки ошибок(не показан). connect(worker, SIGNAL(error(QString)), this, SLOT(errorHandler(QString))); // Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы. connect(thread, SIGNAL(started()), worker, SLOT(process())); // По завершению выходим из потока, и удаляем рабочий класс connect(worker, SIGNAL(finished()), thread, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); // Удаляем поток, после выполнения операции connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start();
Заметка является переводом с форума поддержки разработчиков Blackberry.