Документация Qt для QThread говорит о создании класса из QThread и реализации метода run.
Ниже взята из документации 4.7 Qthread...
Чтобы создать свои собственные потоки, подкласс QThread и reimplement run(). Например:
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
Итак, в каждом отдельном потоке, который я создал, я сделал именно это, и для большинства вещей он работает просто отлично (я не реализую moveToThread (это) в любом из моих объектов, и он отлично работает).
На прошлой неделе я попал в ловушку (удалось пройти через нее, работая там, где я создал свои объекты), и нашел следующее сообщение в блоге. Здесь в основном говорится, что подклассификация QThread действительно не является правильным способом ее выполнения (и что документация неверна).
Это происходит от разработчика Qt, поэтому, на первый взгляд, меня заинтересовало и на дальнейшее размышление, согласитесь с ним. Следуя принципам OO, вы действительно хотите только подклассы класса для дальнейшего улучшения этого класса... не просто использовать методы классов напрямую... вот почему вы создаете экземпляр...
Предположим, что я хотел переместить пользовательский класс QObject в поток... что было бы "правильным" способом сделать это? В этом сообщении в блоге он "говорит", что у него есть пример где-то... но если бы кто-то мог объяснить это мне, это было бы очень признательно!
Update:
Так как этот вопрос получает так много внимания, вот копия и вставка документации 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.