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. [SOLVED] run a function in another thread
QtWS25 Last Chance

[SOLVED] run a function in another thread

Scheduled Pinned Locked Moved General and Desktop
12 Posts 4 Posters 64.5k Views
  • 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.
  • X Offline
    X Offline
    XGuy
    wrote on 3 Oct 2013, 06:52 last edited by
    #1

    Hi,
    Let's say i have a MainWindow and a button on it and on it's button click i want to run a few functions each one in a separate thread. how can i achieve this?

    @void MainWindow::on_pushButton_clicked()
    {
    function1(); // Thread 1
    function2(); // Thread 2
    function3(); // Thread 3
    }@
    these functions are not related to each other so they don't need to be synced together.

    i already tried below code as an example however no luck :-(
    @
    void MainWindow::on_pushButton_clicked()
    {
    QThread thread;
    QThread::currentThread()->setObjectName("MainThread");
    thread.setObjectName("CustomThread");
    MyClass obj;
    obj.moveToThread(&thread);
    thread.start();
    if(thread.isRunning())
    {
    obj.sayHello();
    thread.quit();
    }
    }

    void MyClass::sayHello()
    {
    QString s1 = QThread::currentThread()->objectName();
    }
    @
    i get "MainThread" in s1.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      stevenceuppens
      wrote on 3 Oct 2013, 07:33 last edited by
      #2

      Hi,

      Try this,

      Very easy, and wil run each function in a pool thread,

      Look for QtConcurrent in dicumentation.

      @
      #include <QtConcurrent>

      void MainWindow::on_pushButton_clicked()
      {
      QFuture<void> future = QtConcurrent::run( function1() );  // Thread 1
      QFuture<void> future = QtConcurrent::run( function2() );  // Thread 2
      QFuture<void> future = QtConcurrent::run( function3() );  // Thread 3
      }
      @

      Steven CEUPPENS
      Developer &#x2F; Architect
      Mobile: +32 479 65 93 10

      1 Reply Last reply
      1
      • X Offline
        X Offline
        XGuy
        wrote on 3 Oct 2013, 08:09 last edited by
        #3

        Thanks.
        i tried that and i get: "error: invalid use of void expression"

        1 Reply Last reply
        0
        • X Offline
          X Offline
          XGuy
          wrote on 3 Oct 2013, 08:09 last edited by
          #4

          [quote author="stevenceuppens" date="1380785595"]Hi,

          Try this,

          Very easy, and wil run each function in a pool thread,

          Look for QtConcurrent in dicumentation.

          @
          #include <QtConcurrent>

          void MainWindow::on_pushButton_clicked()
          {
          QFuture<void> future = QtConcurrent::run( function1() );  // Thread 1
          QFuture<void> future = QtConcurrent::run( function2() );  // Thread 2
          QFuture<void> future = QtConcurrent::run( function3() );  // Thread 3
          }
          @[/quote]

          Thanks.
          i tried that and i get: “error: invalid use of void expression”
          and by the way, QFuture is asynchronous so it's not as fast as threads! i need high performance.

          1 Reply Last reply
          1
          • V Offline
            V Offline
            vladstelmahovsky
            wrote on 3 Oct 2013, 08:42 last edited by
            #5

            I think, you have first to read how QThread works, how Qt suggests to use QThreads
            very good example given "here":http://qt-project.org/doc/qt-5.0/qtcore/qthread.html

            1 Reply Last reply
            0
            • S Offline
              S Offline
              stevenceuppens
              wrote on 3 Oct 2013, 08:58 last edited by
              #6

              QThread class itself is not the thread, more the controller..

              indeed, dive into the Docs, to get into QThread..

              Take care with "QFuture is asynchronous so it’s not as fast as threads"..
              depends on what you do.. QFuture "represents the result of an asynchronous computation"

              Below working example of QtConcurrent..
              @

              #include <QCoreApplication>
              #include <QtConcurrent/QtConcurrent>

              // global function
              void myFuncion1()
              {
              qDebug() << "Function1: " << QThread::currentThread();
              }

              class MyClass
              {
              public:
              // static function
              static void myFunction2() { qDebug() << "Function2: " << QThread::currentThread(); }

              // member function
              void myFunction3() { qDebug() << "Function3: " << QThread::currentThread(); }
              

              };

              int main(int argc, char *argv[])
              {
              QCoreApplication a(argc, argv);

              qDebug() << "MainThread: " << QThread::currentThread();
              
              QFuture<void> future1 = QtConcurrent::run( myFuncion1 );  // Thread 1
              
              QFuture<void> future2 = QtConcurrent::run( MyClass::myFunction2 );  // Thread 2
              
              MyClass myClass;
              QFuture<void> future3 = QtConcurrent::run( myClass, &MyClass::myFunction3 );  // Thread 3
              
              return a.exec&#40;&#41;;
              

              }
              @

              Steven CEUPPENS
              Developer &#x2F; Architect
              Mobile: +32 479 65 93 10

              1 Reply Last reply
              0
              • X Offline
                X Offline
                XGuy
                wrote on 3 Oct 2013, 09:01 last edited by
                #7

                [quote author="vladstelmahovsky" date="1380789761"]I think, you have first to read how QThread works, how Qt suggests to use QThreads
                very good example given "here":http://qt-project.org/doc/qt-5.0/qtcore/qthread.html[/quote]

                thanks for the link, it was helpful.
                but there is something in that example which differs from my case!
                @Controller() {
                Worker *worker = new Worker;
                worker->moveToThread(&workerThread);
                connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
                connect(this, &Controller::operate, worker, &Worker::doWork); // here
                connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                workerThread.start();
                }@

                connect(this, &Controller::operate, worker, &Worker::doWork); //
                i dont have signals like "operate" in here, i just want to run a function
                not a slot! so i'm not using signals and slot approach. i just simply want to run a function(not a slot because i dont have a signal for it) in a separate thread.

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jazzycamel
                  wrote on 3 Oct 2013, 09:04 last edited by jazzycamel
                  #8

                  If you want to do it with QThread rather than QtConcurrent then the following is a full, simple example:

                  myobject.h

                  #ifndef MYOBJECT_H
                  #define MYOBJECT_H
                  
                  #include <QObject>
                  
                  class MyObject : public QObject
                  {
                      Q_OBJECT
                  public:
                      explicit MyObject(QObject *parent = 0);
                          
                  public slots:
                      void sayHello();
                  };
                  
                  #endif // MYOBJECT_H
                  

                  myobject.cpp

                  #include "myobject.h"
                  #include <QDebug>
                  #include <QThread>
                  
                  MyObject::MyObject(QObject *parent) : QObject(parent) {}
                  
                  void MyObject::sayHello(){
                      qDebug() << "Hello from: " << QThread::currentThread()->objectName();
                  }
                  

                  main.cpp

                  #include <QtCore/QCoreApplication>
                  #include <QThread>
                  #include <QObject>
                  #include "myobject.h"
                  
                  int main(int argc, char *argv[])
                  {
                      QCoreApplication a(argc, argv);
                      
                      QThread::currentThread()->setObjectName("Main Thread");
                  
                      MyObject myObject;
                  
                      QThread thread;
                      thread.setObjectName("My Thread");
                      QObject::connect(&thread, SIGNAL(started()), &myObject, SLOT(sayHello()));
                      QObject::connect(&thread, SIGNAL(finished()), &a, SLOT(quit()));
                  
                      myObject.moveToThread(&thread);
                      thread.start();
                  
                      return a.exec();
                  }
                  

                  You can't call a method of an object in another thread directly so instead you use signals and slots, which are thread safe, to it for you and to inform you of when the thread has started and finished.

                  Hope this helps ;o)

                  For the avoidance of doubt:

                  1. All my code samples (C++ or Python) are tested before posting
                  2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
                  1 Reply Last reply
                  3
                  • X Offline
                    X Offline
                    XGuy
                    wrote on 3 Oct 2013, 09:22 last edited by
                    #9

                    thanks guys your information was very helpful and now i have a better understanding of QThread and QFuture :-).

                    • You can’t call a method of an object in another thread directly so instead you use signals and slots.*

                    this was my ambiguity in QThread. thanks a million.

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      stevenceuppens
                      wrote on 3 Oct 2013, 09:22 last edited by
                      #10

                      @jazzycamel

                      You can cal a method directly trough the new Qt5 connect syntax,
                      example below works, but do you know its thread-safe?

                      (i think is is.. but not 100% sure... )

                      anyway if you want to be able to use the function

                      "moveToThread()" on your workerObject

                      your worker has to be QObject derived... so making a SLOT in myObject is not that expensive anymore...

                      main.cpp
                      @

                      #include <QCoreApplication>
                      #include <QThread>

                      #include "myobject.h"

                      int main(int argc, char *argv[])
                      {
                      QCoreApplication a(argc, argv);

                      QThread::currentThread()->setObjectName("Main Thread");
                      
                      MyObject myObject;
                      
                      QThread thread;
                      thread.setObjectName("My Thread");
                      
                      QObject::connect(&thread, &QThread::started, &myObject, &MyObject::doSomething);
                      QObject::connect(&thread, SIGNAL(finished()), &a, SLOT(quit()));
                      
                      myObject.moveToThread(&thread);
                      thread.start();
                      
                      return a.exec&#40;&#41;;
                      

                      }
                      @

                      myobject.h
                      @

                      #ifndef MYOBJECT_H
                      #define MYOBJECT_H

                      #include <QObject>

                      class MyObject : public QObject
                      {
                      Q_OBJECT

                      public:
                      explicit MyObject(QObject *parent = 0);

                      void doSomething();
                      

                      };

                      #endif // MYOBJECT_H
                      @

                      myobject.cpp
                      @
                      #include "myobject.h"
                      #include <QDebug>
                      #include <QThread>

                      MyObject::MyObject(QObject *parent) :
                      QObject(parent)
                      {
                      }

                      void MyObject::doSomething()
                      {
                      qDebug() << "Hello from: " << QThread::currentThread()->objectName();
                      }
                      @

                      Steven CEUPPENS
                      Developer &#x2F; Architect
                      Mobile: +32 479 65 93 10

                      1 Reply Last reply
                      0
                      • X Offline
                        X Offline
                        XGuy
                        wrote on 3 Oct 2013, 09:28 last edited by
                        #11

                        i see!
                        so it's only the matter of being thread safe or not!
                        hmmm... you're right, it's really a hard job to make sure your function is thread safe.
                        Thank you all.

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          jazzycamel
                          wrote on 3 Oct 2013, 09:55 last edited by
                          #12

                          Using signals and slots to communicate between threads is thread-safe by intent and design as the long as the connection type is appropriate (something Qt will establish for itself if you use the default value of Qt.AutoConnection).

                          QObject's themselves are not guaranteed to be thread safe, it is up to the developer to ensure their own implementation using QObject is thread-safe. As long as care is taken when accessing any shared objects (mutex's, semaphores etc) it shouldn't be too onerous.

                          I have used the method outlined in my exmaple for creating numerous threads in numerous projects without issue and it is certainly a safer and more reliable method than subclassing QThread itself (IMHO).

                          For the avoidance of doubt:

                          1. All my code samples (C++ or Python) are tested before posting
                          2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
                          1 Reply Last reply
                          0

                          10/12

                          3 Oct 2013, 09:22

                          • Login

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