Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QThread emit resultReady can't trigger slot
Forum Updated to NodeBB v4.3 + New Features

QThread emit resultReady can't trigger slot

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 1.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    changtj
    wrote on last edited by changtj
    #1

    example address
    http://doc.qt.io/qt-5/qthread.html

    i create one console project. the whole code as follow.

    //main.cpp
    #include <QCoreApplication>
    #include <QTimer>
    #include "task.h"
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Task * task = new Task( &a);
    
        QObject::connect( task, SIGNAL(finished()), &a, SLOT(quit()));
    
        QTimer::singleShot( 0, task, SLOT(run()));
    
        return a.exec();
    }
    
    //task.h
    #ifndef TASK_H
    #define TASK_H
    
    #include <QObject>
    
    class Task : public QObject
    {
        Q_OBJECT
    public:
        Task(QObject *parent = 0) : QObject(parent) {}
    
    public slots:
        void run();
    signals:
        void finished();
    };
    
    #endif // TASK_H
    
    //task.cpp
    #include "task.h"
    #include <QPointer>
    #include <iostream>
    #include "controller.h"
    
    QPointer<Controller> ptrControl = 0;
    void Task::run()
    {
        char input[128];
        while( true){
    
            std::cout << "please input \r\n";
            std::cin >>input;
            QString qStrInput;
            qStrInput = input;
            if( qStrInput == "exit"){
                if( ptrControl){
                    ptrControl->deleteLater();
                }
                break;
            }
            else if( "new" == qStrInput ){
                if( ptrControl == 0){
                    ptrControl = new Controller();
                }
                continue;
            }
            else if( "test" == qStrInput ){
                if( ptrControl){
                    ptrControl->MyTest();
                }
                continue;
            }
        }
    
        emit finished();
    }
    
    //controller.h
    #ifndef CONTROLLER_H
    #define CONTROLLER_H
    
    #include <QObject>
    #include <QThread>
    #include <QDebug>
    #include "worker.h"
    
    
    class Controller : public QObject
    {
        Q_OBJECT
        QThread workerThread;
        public:
            Controller() {
                Worker *worker = new Worker;
                worker->moveToThread(&workerThread);
                connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                connect(this, &Controller::operate, worker, &Worker::doWork);
                connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                workerThread.start();
            }
            ~Controller() {
                workerThread.quit();
                workerThread.wait();
            }
        public slots:
            void handleResults(const QString & r){
                QString tx = r;
                qDebug() << tx;
            }
        signals:
            void operate(const QString &);
    public:
            void MyTest(){
                emit operate( "test...");
            }
    };
    
    #endif // CONTROLLER_H
    
    // worker.h
    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    
    class Worker : public QObject
    {
        Q_OBJECT
    
        public slots:
            void doWork(const QString &parameter) {
                QString result;
                result = parameter;
                /* ... here is the expensive or blocking operation ... */
                emit resultReady(result);
            }
    
        signals:
            void resultReady(const QString &result);
    };
    
    #endif // WORKER_H
    
    
    JKSHJ 1 Reply Last reply
    0
    • C changtj

      example address
      http://doc.qt.io/qt-5/qthread.html

      i create one console project. the whole code as follow.

      //main.cpp
      #include <QCoreApplication>
      #include <QTimer>
      #include "task.h"
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          Task * task = new Task( &a);
      
          QObject::connect( task, SIGNAL(finished()), &a, SLOT(quit()));
      
          QTimer::singleShot( 0, task, SLOT(run()));
      
          return a.exec();
      }
      
      //task.h
      #ifndef TASK_H
      #define TASK_H
      
      #include <QObject>
      
      class Task : public QObject
      {
          Q_OBJECT
      public:
          Task(QObject *parent = 0) : QObject(parent) {}
      
      public slots:
          void run();
      signals:
          void finished();
      };
      
      #endif // TASK_H
      
      //task.cpp
      #include "task.h"
      #include <QPointer>
      #include <iostream>
      #include "controller.h"
      
      QPointer<Controller> ptrControl = 0;
      void Task::run()
      {
          char input[128];
          while( true){
      
              std::cout << "please input \r\n";
              std::cin >>input;
              QString qStrInput;
              qStrInput = input;
              if( qStrInput == "exit"){
                  if( ptrControl){
                      ptrControl->deleteLater();
                  }
                  break;
              }
              else if( "new" == qStrInput ){
                  if( ptrControl == 0){
                      ptrControl = new Controller();
                  }
                  continue;
              }
              else if( "test" == qStrInput ){
                  if( ptrControl){
                      ptrControl->MyTest();
                  }
                  continue;
              }
          }
      
          emit finished();
      }
      
      //controller.h
      #ifndef CONTROLLER_H
      #define CONTROLLER_H
      
      #include <QObject>
      #include <QThread>
      #include <QDebug>
      #include "worker.h"
      
      
      class Controller : public QObject
      {
          Q_OBJECT
          QThread workerThread;
          public:
              Controller() {
                  Worker *worker = new Worker;
                  worker->moveToThread(&workerThread);
                  connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                  connect(this, &Controller::operate, worker, &Worker::doWork);
                  connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                  workerThread.start();
              }
              ~Controller() {
                  workerThread.quit();
                  workerThread.wait();
              }
          public slots:
              void handleResults(const QString & r){
                  QString tx = r;
                  qDebug() << tx;
              }
          signals:
              void operate(const QString &);
      public:
              void MyTest(){
                  emit operate( "test...");
              }
      };
      
      #endif // CONTROLLER_H
      
      // worker.h
      #ifndef WORKER_H
      #define WORKER_H
      
      #include <QObject>
      
      class Worker : public QObject
      {
          Q_OBJECT
      
          public slots:
              void doWork(const QString &parameter) {
                  QString result;
                  result = parameter;
                  /* ... here is the expensive or blocking operation ... */
                  emit resultReady(result);
              }
      
          signals:
              void resultReady(const QString &result);
      };
      
      #endif // WORKER_H
      
      
      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      @changtj This is the main thing you must remember: A while(true) loop blocks the event loop, so your main thread cannot process any signals from other threads. Do not mix infinite loops with signals and slots.

      Your Worker object emits the Worker::resultReady() signal, but the slot in the main thread cannot run until your while loop stops.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      C 1 Reply Last reply
      2
      • JKSHJ JKSH

        @changtj This is the main thing you must remember: A while(true) loop blocks the event loop, so your main thread cannot process any signals from other threads. Do not mix infinite loops with signals and slots.

        Your Worker object emits the Worker::resultReady() signal, but the slot in the main thread cannot run until your while loop stops.

        C Offline
        C Offline
        changtj
        wrote on last edited by
        #3

        @JKSH

        yes, it is what you said.
        when i change "while( true)" to "if (true)", it is ok.
        How can i get one "user loop input " application? thanks a lot.

        JKSHJ 1 Reply Last reply
        0
        • C changtj

          @JKSH

          yes, it is what you said.
          when i change "while( true)" to "if (true)", it is ok.
          How can i get one "user loop input " application? thanks a lot.

          JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #4

          @changtj said in QThread emit resultReady can't trigger slot:

          How can i get one "user loop input " application?

          Choose one thread to run your "user loop". This thread should not run an event loop, which means it should not receive any signals. However, it can still emit signals.

          Notes:

          • QCoreApplication::exec() starts an event loop. This prepares your main thread to receive signals.
          • By default, QThread::start() calls QThread::exec() in the new thread. This prepares your new thread to receive signals. (This also allows your Worker Objects to have Slots that run in that thread)
          • To create a thread that doesn't run an event loop, don't use the Worker Object approach. Instead, you can subclass QThread and reimplement QThread::run(), or use QtConcurrent::run(), or use std::thread.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          2

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved