目录
一、继承QThread方式缺点
二、QThread的改进
三、新创建线程方式--信号槽
四、小结
五、完整代码
早期Qt软件版本只能提供继承QThread的方式创建新线程,这是跟面向对象程序设计的早期有关,当时习惯于工程中用继承的方式去扩展系统的功能,那这样创建的线程有什么意义吗?
1、通过QThread继承实现的线程是没有任何意义的;
2、QThread的线程子类仅仅只有受保护的run()函数接口是不同的,其他接口完全是相同的;
3、QThread对应于操作系统中的线程;
4、QThread用于充当一个线程操作的集合;
5、应该提供更灵活的方式去实现线程入口函数;
6、尽量避免重写run函数。
1、早期QThread的内部实现
class QThread : public QObject
{
// ...
// ...
protected:
virtual void run() = 0;
// ...
};
2、现代Qt创建新线程的内部实现
class QThread : public QObject
{
Q_OBJECT
// ...
protected:
virtual void run()
{
(void)exec;
}
// ...
};
早期的QThread子类必须重写run()函数,而现代Qt不在是纯虚函数了,类的本身就已经对run()函数进行了默认的实现,启动了事件循环,这就意味着可以利用信号槽的方式去创建新线程。
现代软件提倡通过以组合的方式去替代继承,从而Qt5之后引入新的创建新线程的方式,不再继续通过继承QThread的方式,也是Qt提倡使用的,也就是通过信号槽的方式去启动新的线程,通过moveToThread()的方式去改变当前对象线程的依附性。
1、创建一个业务类继承于QObject;
//! 1、创建一个业务类继承于QObject
class NewThreadCreate : public QObject
2、在类中定义一个槽函数Tmain()作为线程的入口函数;
private slots:
//! 2、在类中定义一个槽函数Tmain()作为线程的入口函数
void Tmain();
3、在类中定义一个QThread对象m_thread;
//! 3、在类中定义一个QThread对象m_thread
QThread m_thread;
4、通过moveToThread()改变当前对象线程的依附性至m_thread;
//! 4、通过moveToThread()改变当前对象线程的依附性至m_thread
moveToThread(&m_thread);
5、连接新线程m_thread的start()信号到Tmain()槽函数。
//! 5、连接新线程m_thread的start()信号到Tmain()槽函数
QObject::connect(&m_thread, &QThread::started, this, &NewThreadCreate::Tmain);
1、早期Qt版本只能通过继承的方式创建新线程;
2、现代软件技术提倡以组合的方式代替继承;
3、QThread应该作为线程操作集合而使用;
4、可以通过信号与槽的方式灵活指定线程的入口函数。
1、NewThreadCreate.h
#ifndef NEWTHREADCREATE_H
#define NEWTHREADCREATE_H
#include
#include
#include
//! 1、创建一个业务类继承于QObject
class NewThreadCreate : public QObject
{
Q_OBJECT
//! 3、在类中定义一个QThread对象m_thread
QThread m_thread;
public:
NewThreadCreate();
~NewThreadCreate();
void Start();
void Exit(int e);
void Terminate();
private slots:
//! 2、在类中定义一个槽函数Tmain()作为线程的入口函数
void Tmain();
};
#endif // NEWTHREADCREATE_H
2、NewThreadCreate.cpp
#include "NewThreadCreate.h"
NewThreadCreate::NewThreadCreate()
{
//! 4、通过moveToThread()改变当前对象线程的依附性至m_thread
moveToThread(&m_thread);
//! 5、连接新线程m_thread的start()信号到Tmain()槽函数
QObject::connect(&m_thread, &QThread::started, this, &NewThreadCreate::Tmain);
}
void NewThreadCreate::Tmain()
{
qDebug() << "NewThreadCreate: " << QThread::currentThreadId();
}
NewThreadCreate::~NewThreadCreate()
{
// 进行线程同步
m_thread.wait();
}
void NewThreadCreate::Start()
{
m_thread.start();
}
void NewThreadCreate::Exit(int e)
{
m_thread.exit(e);
}
void NewThreadCreate::Terminate()
{
m_thread.terminate();
}
3、在主线程中启动子线程
QThreadMoToThread::QThreadMoToThread(QWidget *parent)
: QWidget(parent)
{
qDebug() << "主线程: " << QThread::currentThreadId();
//! 创建子线程
m_thread = new NewThreadCreate();
m_thread->Start();
}