QT——QThread线程

1、QTread 不是在 main 中开始,而是在run开始运行。
2、QTread 开始start(),通过调用run()执行线程。
3、start()如果试图开始一个已经运行的线程,这个调用将一直等待,直到这个线程完成,然后再重新开始这个线程。
4、run() 方法是纯虚的函数,为了能够做有用的工作必须在继承类中被重新实现。run()中的执行语句都是在新起的一个线程中执行,默认实现是QThread::exec(),表示开始线程的消息循环,就可以接收信号,并执行相应的槽。

=================================================================================
5、Qt 的线程与事件循环
1、不推荐的实现方式>>>>>>>>1
#defineDUMMY_H
#include<QObject>
#include<qDebug>
#include<QThread>
classDummy:publicQObject
{
  Q_OBJECT
public:
  explicitDummy(QObject*parent=0);
publicslots:
  voidemitsig(){
  qDebug()<<"Dummythread:"<<QThread::currentThreadId();
  emitsig();
}
signals:
  voidsig();
};
#endif//
DUMMY_H
===============================================================================
#ifndefTHREAD_H
#defineTHREAD_H
#include<QThread>
#include<qDebug>
//===================================================================================//
//Qt::DirectConnection:When emitted, the signal is immediately delivered to the slot.
//不能跨线程传递消息。
//===================================================================================//
//Qt::QueuedConnection
//When emitted, the signal is queued until the event loop is able to deliver it to the slot.
//将信号包装成QEvent消息,放到消息队列里,QApplication::exec或者线程的QThread::exec()会从消息队列里取消息,然后调用 signal关联的 slot。这种方式既可以在线程内传递消息,也可以跨线程传递消息。     对应的槽函数在接收者所依附的线程中执行。

//===================================================================================//

//Qt::AutoConnection
//If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly,as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.
//这种连接类型根据signal和slot是否在同一个线程里,自动选择Qt::DirectConnection或Qt::QueuedConnection。
//===================================================================================//

//QThread 依附的线程,就是执行构造出此线程的线程,即主线程
//QThread 管理的线程,就是 run 启动的线程,即次线程
//默认连接(AutoConnection)情况下,由于消息的传递是跨线程的,故表现为队列连接(QueuedConnection),同时QThread的对象依附在主线程中,所以它的 slot 函数会在主线程中执行,而不是QTread对象的线程,即次线程中执行。除非信号发射和接收都在次线程中(通过movetoThread 将QTread 对象依附到次线程中)———— Bradley T. Hughes 不支持这种方式。

//===================================================================================//

classThread:publicQThread
{
Q_OBJECT
public:
Thread(QObject*parent=0):QThread(parent)
{ //此时自动连接等同于队列连接,即槽函数在接受者所依附线程执行
  moveToThread(this);//故改变依附的线程,也就是自己,使其依附的线程为次线程,信号和slot在同一个线程中
}
publicslots:
  voidslot_main()//如果没有moveToThread(this),此槽函数在依附线程,即主线程中执行
  {  
    qDebug()<<"fromthreadslot_main:"<<currentThreadId();
  }
protected:
  voidrun()//在新线程中执行
  {
     qDebug()<<"threadthread:"<<currentThreadId();
     exec();
  }
};
#endif//THREAD_H
===============================================================================
#include<QCoreApplication>
#include"dummy.h"
#include"thread.h"
#include<qDebug>
intmain(intargc,char*argv[])
{
  QCoreApplicationa(argc,argv);
  qDebug()<<"mainthread:"<<QThread::currentThreadId();
  Threadthread;
  Dummydummy;
  QObject::connect(&dummy,SIGNAL(sig()),&thread,SLOT(slot_main()));
  thread.start();
  dummy.emitsig();//发射sig()信号
  returna.exec();
}
================================================================================

Bradley T. Hughes推荐的方式:

1.在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。
2.从Qt4.4开始,
qthreads-no-longer-abstract,run 默认调用 QThread::exec(),
则不需要子类化 QThread ,只需要子类化一个QObject 就够了。

3.QThread应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。
4.QObject的子类提供运行的代码中,然后将QObject子类的对象 moveToThread 到新线程QTread子类中。

--------------------------->>>>>>>>2
#ifndefDUMMY_H
#defineDUMMY_H
#include<QThread>
#include<qDebug>
classDummy:publicQThread
{
  Q_OBJECT
  public:
    explicitDummy(QObject*parent=0);
  signals:
    voidsig();
  publicslots:
    voidemitsig()
   {
     emitsig();
   }
};
#endif//DUMMY_H
===============================================================================
#ifndefOBJECT_H
#defineOBJECT_H
#include<QObject>
#include<qDebug>
#include<QThread>
classObject:publicQObject
{
Q_OBJECT
public:
  explicitObject(QObject*parent=0);
signals:
publicslots:
voidslot()
{
  qDebug()<<"fromthreadslot:"<<QThread::currentThreadId();
}
};
#endif//OBJECT_H
==============================================================================
#include"dummy.h"
#include"object.h"
#include<QCoreApplication>
#include<qDebug>
intmain(intargc,char**argv){
  QCoreApplicationa(argc,argv);
  qDebug()<<"mainthread:"<<QThread::currentThreadId();
  QThreadthread;
  Objectobj;
  Dummydummy;
  obj.moveToThread(&thread);

  QObject::connect(&dummy,SIGNAL(sig()),&obj,SLOT(slot()));
  thread.start();

  dummy.emitsig();


  returna.exec();

}


参考:Qt 的线程与事件循环
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值