##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 virtual run() { 。。。需要运行的代码块。。。 }
};
int main(int argc, char** argv)
{
...
ThreadName thread;
Thread.start(); //通过执行start()函数来启动线程
...
}
#ifndef THREADWORK_H
#define THREADWORK_H
#include
#include
class ThreadWork : public QThread
{
Q_OBJECT
public:
ThreadWork(int _index);
void printMessages();
signals:
void SendMessage(const QString&);
private:
int _index;
protected:
void virtual run();
};
#endif // THREADWORK_H
threadwork.cpp
#include "threadwork.h"
#include
#include
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
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(槽函数)); //连接信号和槽
}
#ifndef DOWORK_H
#define DOWORK_H
#include
#include
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
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()<<"线程结束";
}
我们将
dw = new DoWork(); 改为dw = new DoWork(this); 添加一个父对象;
结果显示并没有存在新的线程;
注意: