Qt5.12中两种线程操作的方法

1. 通过创建QTread子实现run()函数来实现

  • QThread::run()是线程的入口 相当于 main函数一样 创建的线程通过调用start()来执行run(); run() 是一个虚函数 通过子类实现方法

  • 大概的框架:

  • class ThreadName:public QThread 
    { 
        Q_OBJECT 
    public: 
        ThreadName(QObject* parent=0):QThread(parent){} 
    public slots:
    signals: 
    protected: 
        void run() { 。。。需要运行的代码块。。。 } 
    }; 
    
    int main(int argc, char** argv) 
    { 
    ... 
    ThreadName thread;
    Thread.start();  //通过执行start()函数来启动线程
    ... 
    }
  • 实例: 
    threadwork.h
  • #ifndef THREADWORK_H
    #define THREADWORK_H
    
    #include <QThread>
    #include <QDebug>
    
    class ThreadWork : public QThread
    {
        Q_OBJECT
    public:
        ThreadWork(int _index);
        void printMessages();
    signals:
        void SendMessage(const QString&);
    private:
        int _index;
    
    protected:
        void run();
    };
    
    #endif // THREADWORK_H

    threadwork.cpp

  • #include "threadwork.h"
    #include <mainwindow.h>
    #include <QDebug>
    
    ThreadWork::ThreadWork(int _index)
    {
        this->_index=_index;
    }
    
    void ThreadWork::printMessages()
    {
        qDebug()<<"printMessage线程id:"<<QString::number((int)QThread::currentThreadId());
    }
    
    void ThreadWork::run()
    {
        qDebug()<<"run()线程id:"<<QString::number((int)QThread::currentThreadId());
        int k =0;
        while(true)
        {
            const QString s = "我是线程:"+QString::number(_index);
            sleep(1);
            emit SendMessage(s);
            if(k==10)
            {
                this->terminate();
                this->wait();
            }
            k++;
         }
    }
    

    Mainwindow.cpp

  • #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        qDebug()<<"主线程id:"<<QString::number((int)QThread::currentThreadId());
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_start_clicked()
    {
         ThreadWork *tw = new   ThreadWork(_current);
         connect(tw,SIGNAL(SendMessage(const QString&)),this,SLOT(ShowMessages(const QString&)));
         tw->printMessages();
         tw->start();
    
         _current++;
    }
    
    void MainWindow::ShowMessages(const QString& SMessages)
    {
        messagesLists+=SMessages;
        QStringListModel * _mode = new QStringListModel(messagesLists);
        this->ui->listView->setModel(_mode);
    }

    运行的结果:


  • 由结果可以看出确实是有两个线程被开启,并且只有run()中的部分在新开启的线程中,其他在创建Qthread这个类对象的线程中,这里是在主线程中;

    注意:信号和槽 是跨线程的 即实现了线程之间的通信;

    2. 通过moveToThread()函数来实现
    作用:将某一个对象从当前的线程中推到另一个线程中,但是不能将其他线程的对象拉到当前线程上;
    原理:其实是通过信号和槽的方式实现;将需要通过线程处理的代码放入到一个槽函数中;
    注意:如果对象存在父对象 则moveToThread()函数不起作用,在帮助文档中的原话是: 
    Changes the thread affinity for this object and its children. The object cannot be moved if it has a parent. Event processing will continue in the targetThread.

    大概框架:
     

    Class doWork : public QObject
    {
        Q_OBJECT
    public:
        explicit DoWork(QObject *parent = 0);
        void qutamde();
    signals:
    
    public slots:
        void qunimade();
    
    }
    
    Int main()
    {
    doWork *dw = new doWork() ;  //实例化类对象
    QThread *t = new QThread();   //实例QThread对象
    Dw->moveToThread(t);        //将槽函数中需要执行的代码放入新创建的线程中执行
    Connect(对象,SIGNAL(对象信号),dw,SLOT(槽函数));   //连接信号和槽
    }
    
  • 实例: 
    dowork.h
  • #ifndef DOWORK_H
    #define DOWORK_H
    
    #include <QObject>
    #include <QThread>
    
    class DoWork : public QObject
    {
        Q_OBJECT
    public:
        explicit DoWork(QObject *parent = 0);
        void qutamde();
    signals:
        void nihao();
    public slots:
        void qunimade();
        void nihaoma();
    };
    
    #endif // DOWORK_H

    dowork.cpp

  • #include "dowork.h"
    #include "QDebug"
    
    DoWork::DoWork(QObject *parent) : QObject(parent)
    {
    
    }
    
    void DoWork::qutamde()
    {
        qDebug()<<"非槽函数 "<<"我的线程id:"+QString::number((int)QThread::currentThreadId());
    }
    
    void DoWork::qunimade()
    {
        qDebug()<<"槽函数 "<<"我的线程id:"+QString::number((int)QThread::currentThreadId());
    }
    
    void DoWork::nihaoma()
    {
        qDebug()<<"你好吗 "<<"我的线程id:"+QString::number((int)QThread::currentThreadId());
    }
    

    Mainwindows.cpp

  • #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        t = new QThread();
        dw = new DoWork();
        dw->moveToThread(t);
        connect(t,SIGNAL(started()),dw,SLOT(qunimade()));
        connect(ui->pushButton,SIGNAL(clicked()),dw,SLOT(nihaoma()));
    
        qDebug()<<"主线程线程id:"<<QString::number((int)QThread::currentThreadId());
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        dw->nihao();
        t->start();
        dw->qutamde();
    
    }
    
    void MainWindow::on_pushButton_2_clicked()
    {
        t->terminate();    //不建议使用这种方法 
        t->wait();         ///
        qDebug()<<"线程结束";
    }
    

  • 可以看出dowork对象中的所有的槽函数都在新的线程中执行,而非槽函数则在创建线程的线程中执行,这里是主线程; 
    我们来验证:The object cannot be moved if it has a parent. 这句话
    我们将 
    dw = new DoWork(); 改为dw = new DoWork(this); 添加一个父对象; 
    - 执行结果: 

  • 结果显示并没有存在新的线程;

    注意:Dw->moveToThread(t); Dw中的槽函数都会被加入到新线程中执行

猜你喜欢

转载自blog.csdn.net/u014453443/article/details/86523652
今日推荐