В документации Qt для QThread сказано создать класс из QThread и реализовать метод run.
Ниже взято из документации 4.7 Qthread ...
Чтобы создать свои собственные потоки, создайте подкласс QThread и переопределите run (). Например:
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket's signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
Итак, в каждом отдельном потоке, который я создал, я делал именно это, и для большинства вещей он отлично работает (я не реализую moveToThread (this) ни в одном из моих объектов, и он отлично работает).
На прошлой неделе я наткнулся на препятствие (мне удалось преодолеть его, работая вокруг того места, где я создавал свои объекты) и нашел следующее сообщение в блоге . Здесь в основном говорится, что создание подкласса QThread действительно не является правильным способом сделать это (и что документация неверна).
Это исходит от разработчика Qt, поэтому с первого взгляда я заинтересовался и после дальнейшего размышления, согласен с ним. Следуя принципам объектно-ориентированного проектирования, вы действительно хотите создать подкласс класса для дальнейшего улучшения этого класса ... а не просто использовать методы классов напрямую ... вот почему вы создаете экземпляр ...
Допустим, я хотел переместить настраиваемый QObject class в поток ... каков будет "правильный" способ сделать это? В этом сообщении в блоге он «говорит», что у него где-то есть пример ... но если бы кто-нибудь мог объяснить его мне, он был бы очень признателен!
Обновление:
Поскольку этот вопрос привлекает столько внимания, вот является копией и вставкой документации 4.8 с «правильным» способом реализации QThread.
class Worker : public QObject
{
Q_OBJECT
QThread workerThread;
public slots:
void doWork(const QString ¶meter) {
// ...
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString)));
connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString)));
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
Я по-прежнему считаю, что стоит отметить, что они включают дополнительный член Worker :: workerThread
, который не нужен и никогда не используется в их примере. Удалите эту часть, и это хороший пример того, как выполнять многопоточность в Qt.