qt5 movetothread 正确的用法

随便你搜索,99%文章都是qthread.start()完事,传参数怎么办?重复运行线程怎么办?

所有坑都写在注释里面了,大家拿去happy吧。

定义线程类,parent必须为空,特别是new的时候:

#ifndef MYTHREAD_H
#define MYTHREAD_H
 
#include <QObject>
#include <QThread>
 
class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread();
 
public slots: // 不定义使用public也行
    void threadRun1(int id){qDebug("id1=%d,tid:%p",id,QThread::currentThread());}
    void threadRun2(int id){qDebug("id2=%d,tid:%p",id,QThread::currentThread());}
signals:
 
};
 
#endif // MYTHREAD_H


偷懒我就不写cpp实现了:

#include "mythread.h"
 
MyThread::MyThread(void)
{
 
}


然后就可以在父类里面开搞了:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include<QThread>
#include"mythread.h"
 
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
signals: // 使用emit来启动线程,并且传参数!
    void threadRun1(int id);
    void threadRun2(int id);
private slots:
    void on_pushButton_clicked();
 
private:
    Ui::MainWindow *ui;
 
    QThread *m_threadRunInBack;
    MyThread *m_myThread;
};
#endif // MAINWINDOW_H

CPP:

#include "mainwindow.h"
#include "ui_mainwindow.h"
 
// msvc编译器中文乱码问题
#ifdef _MSC_VER
#pragma execution_character_set("utf-8")
#endif
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    m_threadRunInBack = new QThread(this);
    
    // parent必须为空,不要传参数,否则提示不能move
    m_myThread = new MyThread();
 
    // 把信号和槽连起来,就可以emit启动线程了!
    connect(this,&MainWindow::threadRun1,m_myThread,&MyThread::threadRun1);
    connect(this,&MainWindow::threadRun2,m_myThread,&MyThread::threadRun2);
    m_myThread->moveToThread(m_threadRunInBack);
}
 
MainWindow::~MainWindow()
{
    delete ui;
    if(m_myThread != nullptr){
        if(m_threadRunInBack->isRunning()){
            qDebug("还在运行");
            m_threadRunInBack->quit();
            m_threadRunInBack->wait();
        }
        //delete m_myThread; // 最后有没有都行!
    }
}
 
// 线程1
void MainWindow::on_pushButton_clicked()
{
    // 就算线程没有循环,执行完函数还是run状态,所以再次启动必须quit!
    if(m_threadRunInBack->isRunning()){
        qDebug("还在运行");
        m_threadRunInBack->quit();
        m_threadRunInBack->wait();
    }
    if(!m_threadRunInBack->isRunning()){
        qDebug("现在启动");
        m_threadRunInBack->start();
 
        // 现在2个函数都在同一个线程运行,牛逼吧?
        emit threadRun1(23);
        emit threadRun2(24);
    }
}

那么剩下一个问题,如果线程里类似QThread::run()循环运行的怎么办???怎么退出呢???留给大家想象,想不到的私信我。

思考2:为什么emit以后,slot的东西就在新的thread中执行了?

首先,movetothread就是移到新线程,如果不用emit,那用什么把当前线程(GUI)和子线程建立起来呢?所以,qt的信号(signal slot)实际就是线程通信的桥梁,由emit来触发另一个子线程最合适不过了。

本文为3YL原创,转载无需联系,但请注明来自labisart.com。

原创文章不易,如果觉得有帮助,可打赏或点击右侧广告支持:

查看打赏记录

发表评论请遵守党国法律!后台审核后方可显示!
  • 最新评论
  • 总共0条评论
  • Blog v1.1© 2024 labisart.com 版权所有 | 联系:labartwork@163.com