Qt5中两种线程操作的方法(附demo)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenyitao736866376/article/details/79733659本人完善代码下载地址:https://download.csdn.net/download/flowerspring/110062751. 通过创建QTread子实现run()函数来实现Q...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenyitao736866376/article/details/79733659
本人完善代码下载地址:https://download.csdn.net/download/flowerspring/11006275
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中的槽函数都会被加入到新线程中执行
更多推荐


所有评论(0)