要使用QRunnable创建线程,步骤如下:
与外界通信方式不同。由于QThread是继承于QObject的,所以可以在线程类中使用信号槽,但QRunnable没有继承于QObject,所以不能使用信号与槽。
启动线程方式不同。QThread线程可以直接调用start()函数启动,而QRunnable线程需要借助QThreadPool进行启动。
资源管理不同。QThread线程对象需要手动去管理删除和释放,而QRunnable则会在QThreadPool调用完成后自动释放。
#ifndef CUSRUNNABLE_H
#define CUSRUNNABLE_H
#include
class CusRunnable : public QRunnable
{
public:
CusRunnable();
~CusRunnable();
void run() override;
};
#endif // CUSRUNNABLE_H
#include "cusrunnable.h"
#include
#include
CusRunnable::CusRunnable()
{
}
CusRunnable::~CusRunnable()
{
qDebug()<<"~CusRunnable";
}
void CusRunnable::run()
{
for(int i=0;i<10;i++)
{
qDebug()<<"doWork %d"<
CusRunnable* run=new CusRunnable();
qDebug()<<"main thread_id="<start(run);
main thread_id= 0x7004
doWork %d 0 thread_id 0x6228
doWork %d 1 thread_id 0x6228
doWork %d 2 thread_id 0x6228
doWork %d 3 thread_id 0x6228
doWork %d 4 thread_id 0x6228
doWork %d 5 thread_id 0x6228
doWork %d 6 thread_id 0x6228
doWork %d 7 thread_id 0x6228
doWork %d 8 thread_id 0x6228
doWork %d 9 thread_id 0x6228
~CusRunnable
上面说到启动QRunnable线程需要QThreadPool,而调用方式有两种:全局线程池和非全局线程池。
全局线程池如上面示例中。非全局线程池其实就是自己实例化一个QThreadPool对象,我们可以控制线程最大数量等。
CusRunnable* run=new CusRunnable();
qDebug()<<"main thread_id="<
因为QRunnable没有继承于QObject,所以没法使用信号与槽。QRunnable与外界通信有两种方式:
函数定义如下:
[static] bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument( Q_NULLPTR ), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument())
该函数就是尝试调用obj的member函数,可以是信号、槽或者Q_INVOKABLE声明的函数(能够被Qt元对象系统唤起),如果调用成功,返回true,失败返回false。
QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式Qt::ConnectionType type。如果type为Qt::DirectConnection,则为同步调用,若为Qt::QueuedConnection,则为异步调用。
首先,我们在使用CusRunnable类的类中定义如下函数:
Q_INVOKABLE void onResultReady(const QString result);
void SIHToolBar::onResultReady(const QString result)
{
qDebug()<<"onResultReady result="<CusRunnable(QObject* obj);
最后,我们在run函数中调用这个对象的函数。
void CusRunnable::run()
{
for(int i=0;i<10;i++)
{
qDebug()<<"doWork %d"<