The use of Qthread __QT

Source: Internet
Author: User
Tags emit thread class
Overview

The Qthread class provides a platform-independent way to manage threads. A Qthread object manages a thread. The execution of Qthread begins with the execution of the run () function, and in the Qthread class of Qt, the run () function initiates the event loop mechanism by invoking the Exec () function, and processes the QT events within the thread. The main purpose of creating threads in Qt is to use threads to handle time-consuming background operations so that the main interface can respond to user requests in a timely manner. There are two ways to use Qthread:

Qobject::movetothread ()

Inherit Qthread class

The following is a detailed description of the methods and examples to describe the two methods. method One. The Qobject::movetothread () method Description defines a worker class that inherits from QObject and defines a slot slot function in the Worker Class DoWork (), which defines the work that a thread needs to do.

In the controller class where you want to use the thread, create a new Qthread object and Woker class object, and use the Movetothread () method to leave the Worker object's event loop to the Qthread object for processing.

The associated signal function and slot function are established to connect, and then the signal is emitted to trigger the slot function of Qthread to make it perform work. Examples of Movetothread

First, create a new work class that focuses on its dowork slot function, which defines the work that a thread needs to do and sends a signal to trigger it. All functions are defined in the header file of the Wrok class, and the CPP file is empty, so it is not posted.

Wroker.h

Work defines the work that a thread is to perform
#ifndef worker_h
#define WORKER_H
#include <QObject>
#include <qdebug >
#include <QThread>
class Worker:public QObject
{
    q_object public
:
    Worker ( qobject* parent = nullptr) {} Public
slots:
        //dowork defines the action to be performed by the thread
    void doWork (int parameter)
    {
        qdebug () << "receive the Execute signal---------------------------------";
        Qdebug () << "Current     thread ID:" <<qthread::currentthreadid ();
       Loop 1 million times for
       (int i = 0;i!=1000000;++i)
       {
        ++parameter
       }
       Send End Signal
       qdebug () << "      finish the work and sent the Resultready signal\n";
       Emit resultready (parameter);
    }

The signal sent when the thread completes work
signals:
    void Resultready (const int result);

#endif//Worker_h

Then define a controller class that defines a Qthread object for handling the event looping work of a worker object.

Controller.h

#ifndef controller_h
#define CONTROLLER_H
#include <QObject>
#include <QThread>
# Include<qdebug>
//controller is used to start the thread and process the thread execution results
class Controller:public QObject
{
    q_object
    Qthread workerthread;
Public:
    Controller (QObject *parent= nullptr);
    ~controller ();

Public slots:
    //processing thread execution result
    void handleresults (const int rslt)
    {
        qdebug () << receive the Resultready signal---------------------------------";
        Qdebug () << "Current     thread ID:" <<qthread::currentthreadid () << ' \ n ';
        Qdebug () << "The last result is     :" <<rslt;
    }
Signals:
    //Send signal triggers thread
    void operate (const int);

#endif//Controller_h

Controller The CPP file for the class, creates a worker object in its constructor, and hands its event loop to the Workerthread object to process, finally starts the thread, and then triggers its event-handler function.

Controller.cpp

 #include "controller.h" #include <worker.h> controller::controller (QObject *parent):
    QObject (parent) {worker *worker = new worker;
    Call Movetothread to give the task to Workthread Worker->movetothread (&workerthread);
    Operate signal launch after start thread work connect (this, SIGNAL (operate (const int)), worker, SLOT (doWork (int)));
    The thread ends when the Connect is destroyed (&workerthread, &qthread::finished, worker, &qobject::d eletelater);
    The thread ends up sending a signal to process the results connect (worker, SIGNAL (resultready (int)), this, SLOT (handleresults (int)));
    Start thread Workerthread.start ();
    Launch signal, start execution qdebug () << "emit the signal to execute!---------------------------------";
    Qdebug () << "Current thread ID:" <<qthread::currentthreadid () << ' \ n ';
Emit operate (0);
    The Quit () function ends the thread Controller::~controller () {workerthread.quit () in the destructor ().
Workerthread.wait (); }

Next is the main function, in which we create a new controller object and start executing:

main.cpp

#include <QCoreApplication>
#include "controller.h"
#include <QDebug>
#include <qthread >
int main (int argc, char *argv[])
{
    qdebug () << "I am Main Thread, my ID:" <<qthread:: Currentthreadid () << "\ n";
    Qcoreapplication A (argc, argv);

    Controller C;
    return a.exec ();
}
operation result and explanation


Run Results screenshot 1
The main function prints the current thread number, that is, the thread number of the primary thread is 0X7A4, continues to print the current thread number in the controller constructor, is also the main thread number, after handing the work class to the child thread, sends the signal to the child thread, the child thread receives the signal to begin executing, Its thread number is 0x1218, the execution end sends the signal to controller processing result.

method Two. Methods of inheriting Qthread method describes a class mythread that inherits Qthread, overloads the Run () function in the mythread, and writes the work to be performed in the run () function.

Call the start () function to start the thread. example of inheriting Qthread

First write the Mythread class, which inherits from Qthread, which customizes the signal slot and rewrites the run function. The header file is as follows:

MyThread.h

#ifndef mythread_h
#define MYTHREAD_H
#include <QThread>
#include <QDebug>
class Mythread:public qthread
{
    q_object public
:
    mythread (qobject* parent = nullptr);
    Custom sent signal
signals:
    void mythreadsignal (const int);
    Custom slot Public
slots:
    void Mythreadslot (const int);
Protected:
    void Run () override;

#endif//Mythread_h

MyThread.cpp

#include "mythread.h"

mythread::mythread (QObject *parent)
{

}

void Mythread::run ()
{
    Qdebug () << "Mythread run () start to execute";
    Qdebug () << "Current     thread ID:" <<qthread::currentthreadid () << ' \ n ';
    Loop 1 million times
    int count = 0;
    for (int i = 0;i!=1000000;++i)
    {
     ++count
    }
    Send End signal
    emit mythreadsignal (count);
    exec ();
}

void Mythread::mythreadslot (const int val)
{
    qdebug () << Mythreadslot () start to execute;
    Qdebug () << "Current     thread ID:" <<qthread::currentthreadid () << ' \ n ';
    Loop 1 million times
    int count = 888;
    for (int i = 0;i!=1000000;++i)
    {
     ++count
    }
}

Implement this mythread call in the Controller class

Controller.h

#include "mythread.h"

mythread::mythread (QObject *parent)
{

}

void Mythread::run ()
{
    Qdebug () << "Mythread run () start to execute";
    Qdebug () << "Current     thread ID:" <<qthread::currentthreadid () << ' \ n ';
    Loop 1 million times
    int count = 0;
    for (int i = 0;i!=1000000;++i)
    {
     ++count
    }
    Send End signal
    emit mythreadsignal (count);
    exec ();
}

void Mythread::mythreadslot (const int val)
{
    qdebug () << Mythreadslot () start to execute;
    Qdebug () << "Current     thread ID:" <<qthread::currentthreadid () << ' \ n ';
    Loop 1 million times
    int count = 888;
    for (int i = 0;i!=1000000;++i)
    {
     ++count
    }
}

Controller.cpp

#include "controller.h"
#include <mythread.h>
controller::controller (QObject *parent): QObject ( Parent)
{
    mythrd = new Mythread;
    Connect (mythrd,&mythread::mythreadsignal,this,&controller::handleresults);
    The thread ends when the
    Connect is destroyed (MYTHRD, &qthread::finished, this, &qobject::d eletelater);
    Connect (this,&controller::operate,mythrd,&mythread::mythreadslot);
    Start the thread
    mythrd->start ();
    Qthread::sleep (5);
    Emit operate (999);
}

Controller::~controller ()
{
    mythrd->quit ();
    Mythrd->wait ();
}

The contents of the main function are the same as in the previous example, so they are not pasted. Run Results and instructions:


Run Results screenshot 2

By customizing a class that inherits Qthread, instantiate the object of that class, and overload the run () function for the work that needs to be done. Then call the start function where necessary to perform the tasks in the run function. Interestingly, however, after Mythread.start () I triggered a signal from the main function, which corresponds to the slot of the child thread, and the number of the currently executing thread in the slot function of the child thread, and you can see that the thread number of the slot function that executes the child thread is the number of the main thread. comparison of two methods

Two ways to execute threads are OK, whatever you like. But it looks like the second one is simpler and easier to understand. But our interest is in what is the difference between the two methods of use. The biggest difference is that the movetothread approach is to encapsulate all the work we need in a class, define each task as a slot function, then create a signal to trigger the slots, and then connect the signals to the slots, Finally, this class calls the Movetothread method to a Qthread object, and then calls the Qthread start () function to give it full powers to handle the event loop. So, anytime we need a thread to perform a task, we just need to send a corresponding signal. The advantage is that we can define a lot of work that needs to be done in a worker class, and then emit the triggering signal thread to execute it. Compared to subclasses of Qthread can only perform tasks in the run () function, one thread in the Movetothread method can do many different things (as long as the corresponding signal of the task is emitted).

The Qthread method of subclasses is to rewrite the run () function in Qthread and define the required work in the run () function. The result is that when our custom child thread calls the start () function, it starts executing the run () function. If the associated slot functions are defined in a custom thread class, the slot functions are not executed by subclasses of the Qthread itself, but by the thread (typically the main thread) of the child's owner. If you don't understand, see, in the second example, the ID of the current thread is printed in the slot function of the subclass thread, which is the ID of the main thread. Indeed, subclasses of Qthread can only perform tasks in the run () function until the run () function exits, and its slot function is not executed by its own thread at all.

PS:
        The above code is the Qt5.7 development environment, using the VS2015 64-bit compiler. The code can copy and paste directly to run the

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.