如果类型是Qt::BlockingQueuedConnection,该方法将以与Qt::QueuedConnection相同的方式调用,不同的地方:当前线程将阻塞,直到事件被传递。使用此连接类型在同一线程中的对象之间通信将导致死锁。
如果类型是Qt::AutoConnection,如果obj与调用者在同一线程,成员被同步调用;否则,它将异步调用该成员。
我们在主界面中定一个函数,用于更新界面内容:
Q_INVOKABLE void setText(QString msg){ ui->label->setText(msg); }继承于QRunnable的线程类,修改完成如下:
#ifndef INHERITQRUNNABLE_H #define INHERITQRUNNABLE_H #include <QRunnable> #include <QWidget> #include <QDebug> #include <QThread> class CusRunnable : public QRunnable { public: //修改构造函数 explicit CusRunnable(QObject *obj):m_pObj(obj){ } ~CusRunnable(){ qDebug() << __FUNCTION__; } void run(){ qDebug() << __FUNCTION__ << QThread::currentThreadId(); QMetaObject::invokeMethod(m_pObj,"setText",Q_ARG(QString,"hello world!")); //此处与外部通信 QThread::msleep(1000); } private: QObject * m_pObj = nullptr; //定义指针 }; #endif // INHERITQRUNNABLE_H创建线程对象时,需要将主界面对象传入线程类,如下:
m_pRunnable = new CusRunnable(this);到这里也就实现了线程与外部通信了,运行效果如下:
五、小结使用该方法实现的多线程,线程中的资源无需用户手动释放,线程执行完后会自动回收资源;
和继承QThread的方法一样需要继承类,并且重新实现run函数;
需要结合QThreadPool线程池来使用;
与外界通信可以使用如果使用信号槽机制会比较麻烦,可以使用QMetaObject::invokeMethod的方式与外界通信。