原文作者:luoyayun361
原文链接:https://blog.csdn.net/luoyayun361/article/details/97116972
原文更详细,我这里只转载主要使用方法。
QRunnable的用法跟QThread差不多
1)继承QRunnable
2)重写run函数
3)使用QThreadPool启动
QRunnable和QThread的区别
1)通信方式不同。QRunnable不是继承QObject的,不能使用信号与槽来进行通信。
2)启动方式不同。QThread使用start()函数启动,QRunnable使用QThreadPool来启动
3)资源管理不同。QThread需要自己管理资源,而QRunnable在QThreadPool调用完就自动释放资源。
启动方式:
全局线程池和非全局线程池。
全局线程池方式:
QThreadPool::globalInstance()->start(m_pRunnable);
非全局线程池:
QThreadPool threadpool;
threadpool.setMaxThreadCount(1);
threadpool.start(m_pRunnable);
与外界通信:
有两种方法:
1)使用多继承。在自定义线程类的时候同时继承于QRunnable和QObject。但是这种方法要特别注意。
2)使用QMetaObject::invokeMethod。
下面介绍QMetaObject::invokeMethod
QMetaObject::invokeMethod该函数的主要作用尝试调用对象obj的方法member(注意member可以为信号或者是槽),如何member可以被调用,则返回真,否则返回假。
假如我们在主界面中定一个函数,用于更新界面内容:
Q_INVOKABLE void setText(QString msg);
Q_INVOKABLE 的作用是用来修饰成员函数,让被修饰的成员函数能够被元对象系统所唤起
然后线程类需要修改一下:
.h文件
class CusRunnable : public QRunnable
{
public:
explicit CusRunnable(QObject *obj);
~CusRunnable();
void run();
private:
QObject * m_pObj = nullptr;
};
.cpp文件
CusRunnable::CusRunnable(QObject * obj):
m_pObj(obj)
{
}
CusRunnable::~CusRunnable()
{
qDebug() << __FUNCTION__;
}
void CusRunnable::run()
{
qDebug() << __FUNCTION__ << QThread::currentThreadId();
QMetaObject::invokeMethod(m_pObj,"setText",Q_ARG(QString,"this is AA!"));
QThread::msleep(1000);
}
注意,这里的调用方式:
QMetaObject::invokeMethod(m_pObj,“setText”,Q_ARG(QString,“this is AA!”));
其中"setText"就是要调用的函数,传参方式Q_ARG(QString,“this is AA!”),表示传入一个QString类型,值为"this is AA!"
而在创建线程对象时,需要将主界面对象传入线程类:
m_pRunnable = new CusRunnable(this);