只针对qthread不是抽象类的版本
qthread 调用start 默认执行run函数,默认开启事件循环,qhtread的exit() 和quit 函数之后再qthread 进入事件循环内才可以停止,也就是当qthread执行exec() 函数的阶段才会响应exit()和quit 函数。(也就是说调用exit() 或者quit() 函数qthread 会做一个记录,该线程需要退出,但是是否执行需要开启事件循环,也就是qthread 调用exec(),否则永远不执行.terminate() 也可以终止,但是该函数属于破坏式终止,后果未知)
实现的方式有两种:
1.继承qthread 函数重新写run函数(只用run函数执行或者调用的代码在新的线程中执行,其余代码还是在创建新线程的 旧线程中执行,槽函数也只在创建该线程的线程中执行)
void run()
{while( 1){// if(!flag){break;} // 判断是否需要退出循环, flag 的操作在run 函数之外进行}exec() ;// 只有运行到这里,线程才会开启事件循环,执行事件操作,否则不执行// 也只能通过quit() exit() 函数跳出事件循环}
2.如果想让槽函数在新的线程中执行需要,重写继承qobject 的类
class MyObject public : QObject
{
public:MyObject (QObject* parent = nullptr);~MyObject ();
signals:public slots:void doTask();
};
QThread * thread = new QThread(this);
MyObject *myObject = new MyObjct();// 不可以提供父对象
myObject->moveToThread(thread);connect(thread, &QThread::finished, thread, &QObject::deleteLater);connect(thread, &QThread::finished, myObject, &QObject::deleteLater);//设置野指针为nullptrconnect(thread, &QObject::destroyed, this, &MainWindow::setThreadNullptr);connect(myObject, &QObject::destroyed, this, &MainWindow::setObjecNullptr);
如果MyObject 类成员中有qtimer qtcpsocket 或者其他不可以跨线程的类,就需要通过信号与槽来创建对象,否则出错.
如果是在创建myObject 对象的线程中直接调用MyObject 成员函数,那么依然在旧线程中执行。
qobject_cast<QObject*>(QObject* object) 的使用方式
1.object对象必须是继承qobject类
2.必须声明了Q_OBJECT 宏
3.必须正确实现了qobject 中的基础接口,构造函数或者析构函数
4.object 必须被指定当前类为父对象,否则失败MyObject myObject = new MyObject(this);