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. How to use QThread?

How to use QThread?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 5 Posters 258 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.
  • H Offline
    H Offline
    H.dragon
    wrote on last edited by
    #1

    Hello, I'm making some GUI through QT.
    I almost complete my work but QThread doesn't work. When I click the measure button, my GUI just terminates.
    My goal is to measure the position of the encoder (it moves) and display it on the Qtextbrowser. Can you figure out what I did wrong?
    MDCE is a class in mpint.h

    //position.h
    #ifndef POSITION_H
    #define POSITION_H
    
    #include "mpint.h"
    #include <QThread>
    #include <QTextBrowser>
    
    class position :public QThread
    {
        Q_OBJECT
    public:
        position(QThread* parent = nullptr);
        ~position();
        double CurrentLocation(MDCE* com);
        void StartThread(MDCE* com, QTextBrowser* browser);
        void MeasureLocation(MDCE* com, QTextBrowser* browser);
        void stopMeasure();
    private:
        QThread* thread1;
    
    };
    
    
    
    #endif // POSITION_H
    
    //position.cpp
    #include "position.h"
    
    
    position::position(QThread* parent) : QThread(parent)
    {
        thread1 = nullptr;
    }
    
    // Destructor
    position::~position()
    {
        if (thread1 != nullptr)  delete thread1;
    }
    
    
    double position::CurrentLocation(MDCE* com)
    {
        char record[] = "X_enc_pos";
        double location;
        GetVarN(record, &location, 0, com); //this function puts the value of current position to (double) location
        return location;
    }
    
    void position::MeasureLocation(MDCE* com, QTextBrowser* browser)
    {
        double location;
        while (1)
        {
            location = CurrentLocation(com);
            browser->setText(QString::number(location));
            if (QThread::currentThread()->isInterruptionRequested()) return;
        }
    }
    
    void position::StartThread(MDCE* com, QTextBrowser* browser)
    {
    
        thread1 = QThread::create(std::bind(&position::MeasureLocation,this, com, browser));
        thread1->start();
    }
    
    
    void position::stopMeasure()
    {
        thread1->requestInterruption();
        if (!thread1->wait(3000))
        {
            thread1->terminate();
            thread1->wait();
        }
        thread1 = nullptr;
    }
    

    Thank you :)

    jsulmJ JKSHJ 2 Replies Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to the forums.

      You are not allowed to use QTextBrowser * directly from a thread.
      That will crash.
      You must send a signal to main thread and it will talk to the text browser.

      No QWidget of any kind can be directly accessed from threads.

      1 Reply Last reply
      1
      • H H.dragon

        Hello, I'm making some GUI through QT.
        I almost complete my work but QThread doesn't work. When I click the measure button, my GUI just terminates.
        My goal is to measure the position of the encoder (it moves) and display it on the Qtextbrowser. Can you figure out what I did wrong?
        MDCE is a class in mpint.h

        //position.h
        #ifndef POSITION_H
        #define POSITION_H
        
        #include "mpint.h"
        #include <QThread>
        #include <QTextBrowser>
        
        class position :public QThread
        {
            Q_OBJECT
        public:
            position(QThread* parent = nullptr);
            ~position();
            double CurrentLocation(MDCE* com);
            void StartThread(MDCE* com, QTextBrowser* browser);
            void MeasureLocation(MDCE* com, QTextBrowser* browser);
            void stopMeasure();
        private:
            QThread* thread1;
        
        };
        
        
        
        #endif // POSITION_H
        
        //position.cpp
        #include "position.h"
        
        
        position::position(QThread* parent) : QThread(parent)
        {
            thread1 = nullptr;
        }
        
        // Destructor
        position::~position()
        {
            if (thread1 != nullptr)  delete thread1;
        }
        
        
        double position::CurrentLocation(MDCE* com)
        {
            char record[] = "X_enc_pos";
            double location;
            GetVarN(record, &location, 0, com); //this function puts the value of current position to (double) location
            return location;
        }
        
        void position::MeasureLocation(MDCE* com, QTextBrowser* browser)
        {
            double location;
            while (1)
            {
                location = CurrentLocation(com);
                browser->setText(QString::number(location));
                if (QThread::currentThread()->isInterruptionRequested()) return;
            }
        }
        
        void position::StartThread(MDCE* com, QTextBrowser* browser)
        {
        
            thread1 = QThread::create(std::bind(&position::MeasureLocation,this, com, browser));
            thread1->start();
        }
        
        
        void position::stopMeasure()
        {
            thread1->requestInterruption();
            if (!thread1->wait(3000))
            {
                thread1->terminate();
                thread1->wait();
            }
            thread1 = nullptr;
        }
        

        Thank you :)

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @H-dragon To add to @mrjj : why do you inherit QThread and then add a QThread* member?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • H H.dragon

          Hello, I'm making some GUI through QT.
          I almost complete my work but QThread doesn't work. When I click the measure button, my GUI just terminates.
          My goal is to measure the position of the encoder (it moves) and display it on the Qtextbrowser. Can you figure out what I did wrong?
          MDCE is a class in mpint.h

          //position.h
          #ifndef POSITION_H
          #define POSITION_H
          
          #include "mpint.h"
          #include <QThread>
          #include <QTextBrowser>
          
          class position :public QThread
          {
              Q_OBJECT
          public:
              position(QThread* parent = nullptr);
              ~position();
              double CurrentLocation(MDCE* com);
              void StartThread(MDCE* com, QTextBrowser* browser);
              void MeasureLocation(MDCE* com, QTextBrowser* browser);
              void stopMeasure();
          private:
              QThread* thread1;
          
          };
          
          
          
          #endif // POSITION_H
          
          //position.cpp
          #include "position.h"
          
          
          position::position(QThread* parent) : QThread(parent)
          {
              thread1 = nullptr;
          }
          
          // Destructor
          position::~position()
          {
              if (thread1 != nullptr)  delete thread1;
          }
          
          
          double position::CurrentLocation(MDCE* com)
          {
              char record[] = "X_enc_pos";
              double location;
              GetVarN(record, &location, 0, com); //this function puts the value of current position to (double) location
              return location;
          }
          
          void position::MeasureLocation(MDCE* com, QTextBrowser* browser)
          {
              double location;
              while (1)
              {
                  location = CurrentLocation(com);
                  browser->setText(QString::number(location));
                  if (QThread::currentThread()->isInterruptionRequested()) return;
              }
          }
          
          void position::StartThread(MDCE* com, QTextBrowser* browser)
          {
          
              thread1 = QThread::create(std::bind(&position::MeasureLocation,this, com, browser));
              thread1->start();
          }
          
          
          void position::stopMeasure()
          {
              thread1->requestInterruption();
              if (!thread1->wait(3000))
              {
                  thread1->terminate();
                  thread1->wait();
              }
              thread1 = nullptr;
          }
          

          Thank you :)

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

          Hi, and welcome!

          @H-dragon said in How to use QThread?:

          class position :public QThread
          {
              ...
          private:
              QThread* thread1;
          };
          

          Your position class inherits QThread and contains a QThread (thread1) at the same time. I'm sure that's not what you want! (EDIT: @jsulm beat me to it)

          Start by studying some examples, like:

          • https://doc.qt.io/qt-5/qthread.html#details
          • https://doc.qt.io/qt-5/examples-threadandconcurrent.html

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

          1 Reply Last reply
          3
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #5

            You are missing some fundamental concepts of QThread but it's not your fault, this stuff is complicated and the docs, while they improved a lot, still appear confusing to newcomers. Have a look at https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ it's a great read to fix the QThread concept in mind

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            6
            • H Offline
              H Offline
              H.dragon
              wrote on last edited by
              #6

              GUI.png
              @mrjj @jsulm @JKSH @VRonin, Sorry for late reply and Thank you so much! I thought that It will take time to get answer, but you answered right away. I understand that I misunderstood the concept of inheritance.

              But I have another question reading your answers and examples - does QThread require the void function to put all the function in one window? I'm making GUI like the picture I uploaded, which displays the position in the red rectangular line (ex. 50000 count).
              @mrjj said I'm not allowed to use QTestBrowser directly, so I deleted the QtextBrowser and changed working function from void to double like below

              //position.h
              #ifndef POSITION_H
              #define POSITION_H
              
              #include "mpint.h"
              #include <QThread>
              
              class position
              {
              
              public:
                  position();
                  ~position();
                  double CurrentLocation(MDCE* com);
                  void StartThread(MDCE* com);
                  void MeasureLocation(MDCE* com);
                  void stopMeasure();
              private:
                  QThread* thread1;
              
              };
              
              #endif // POSITION_H
              
              #include "position.h"
              
              
              position::position()
              {
                  thread1 = nullptr;
              }
              
              // Destructor
              position::~position()
              {
                  if (thread1 != nullptr)  delete thread1;
              }
              
              
              double position::CurrentLocation(MDCE* com)
              {
                  char record[] = "X_enc_pos";
                  double location;
                  GetVarN(record, &location, 0, com);
                  return location;
              }
              
              
              void position::StartThread(MDCE* com)
              {
              
                  thread1 = QThread::create(std::bind(&position::MeasureLocation,this, com));
                  thread1->start();
              }
              
              double position::MeasureLocation(MDCE* com)
              {
                  double location;
                  while (1)
                  {
                      location = CurrentLocation(com);
                      return location;
                      if (QThread::currentThread()->isInterruptionRequested()) return;
                  }
              }
              
              void position::stopMeasure()
              {
                  thread1->requestInterruption();
                  if (!thread1->wait(3000))
                  {
                      thread1->terminate();
                      thread1->wait();
                  }
                  thread1 = nullptr;
              }
              
              //mainwindow.cpp(this isn't the entire code)
              
              connect(ui->btnMeasurePos, SIGNAL(clicked()), this, SLOT(getPosition()));
              
              
              void MainWindow::getPosition()
              {
                  double posval;
                  pos.StartThread(motor);
                  //I want to get the position double value in some ways
                  ui->statusEncoder->settext~~~~~
                  //display in QTextBrowser
                  //motor is MDCE class, statusEncoder is QTextBrowser
              }
              

              but as I write in mainwindow, I don't know how to display the position while not blocking the main thread works(like move axis). how should I do?
              Sorry for my poor knowledge about C++ and QT.

              jsulmJ 1 Reply Last reply
              0
              • H H.dragon

                GUI.png
                @mrjj @jsulm @JKSH @VRonin, Sorry for late reply and Thank you so much! I thought that It will take time to get answer, but you answered right away. I understand that I misunderstood the concept of inheritance.

                But I have another question reading your answers and examples - does QThread require the void function to put all the function in one window? I'm making GUI like the picture I uploaded, which displays the position in the red rectangular line (ex. 50000 count).
                @mrjj said I'm not allowed to use QTestBrowser directly, so I deleted the QtextBrowser and changed working function from void to double like below

                //position.h
                #ifndef POSITION_H
                #define POSITION_H
                
                #include "mpint.h"
                #include <QThread>
                
                class position
                {
                
                public:
                    position();
                    ~position();
                    double CurrentLocation(MDCE* com);
                    void StartThread(MDCE* com);
                    void MeasureLocation(MDCE* com);
                    void stopMeasure();
                private:
                    QThread* thread1;
                
                };
                
                #endif // POSITION_H
                
                #include "position.h"
                
                
                position::position()
                {
                    thread1 = nullptr;
                }
                
                // Destructor
                position::~position()
                {
                    if (thread1 != nullptr)  delete thread1;
                }
                
                
                double position::CurrentLocation(MDCE* com)
                {
                    char record[] = "X_enc_pos";
                    double location;
                    GetVarN(record, &location, 0, com);
                    return location;
                }
                
                
                void position::StartThread(MDCE* com)
                {
                
                    thread1 = QThread::create(std::bind(&position::MeasureLocation,this, com));
                    thread1->start();
                }
                
                double position::MeasureLocation(MDCE* com)
                {
                    double location;
                    while (1)
                    {
                        location = CurrentLocation(com);
                        return location;
                        if (QThread::currentThread()->isInterruptionRequested()) return;
                    }
                }
                
                void position::stopMeasure()
                {
                    thread1->requestInterruption();
                    if (!thread1->wait(3000))
                    {
                        thread1->terminate();
                        thread1->wait();
                    }
                    thread1 = nullptr;
                }
                
                //mainwindow.cpp(this isn't the entire code)
                
                connect(ui->btnMeasurePos, SIGNAL(clicked()), this, SLOT(getPosition()));
                
                
                void MainWindow::getPosition()
                {
                    double posval;
                    pos.StartThread(motor);
                    //I want to get the position double value in some ways
                    ui->statusEncoder->settext~~~~~
                    //display in QTextBrowser
                    //motor is MDCE class, statusEncoder is QTextBrowser
                }
                

                but as I write in mainwindow, I don't know how to display the position while not blocking the main thread works(like move axis). how should I do?
                Sorry for my poor knowledge about C++ and QT.

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @H-dragon said in How to use QThread?:

                does QThread require the void function to put all the function in one window?

                QThread has nothing to do with windows and you should never change UI from other threads than main thread (this was already mentioned here I think). Your other threads should simply emit signals which can be connected to slots in your UI.

                Did you read what @VRonin suggested to read? I don't know what you're trying to achieve with your latest code...

                Are you actually sure you need threads at all?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                4

                • Login

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