随便你搜索,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来触发另一个子线程最合适不过了。