каков правильный способ реализации QThread… (пример, пожалуйста…)

В документации 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.

62
задан Mogsdad 15 January 2018 в 13:41
поделиться