关于使用QThread需要注意的

一般在Qt中,我们有两种使用线程的方法:

  1. 声明一个类,该类继承QThread,我们只需重写run函数即可,在run函数中实现我们需要在线程中处理的事务。
  2. 声明一个类,该类继承QObject,假设该类实例化成a,调用a.moveToThread()该方法,即可将该对象移动到新线程中,此时对象中的槽函数归属于新线程,也就是信号接收者属于新线程,而且我们也推荐这样做

        

当然,这两种方法网上有一大堆的资料,这里就不在阐述了。而这里我们只探讨几个注意事项:

  • 假设在方法1中实现的类为Thread,该类中实现了槽函数threadSlot:
  • //主线程中编写如下代码
    Thread * thread = new Thread;
    //主线程中的信号test
    connect(this,SIGNAL(test()),thread,SLOT(threadSlot()));
    thread->start();
    emit test();
    
    

    此时该槽函数将会在主线程中执行,无论connect的第五个参数是什么,原因如下:

            该线程由主线程创建,除了Thread中的run函数外,其余都属于主线程,

            当调用Qt::DirectConnection时,槽函数由发射信号所在的线程执行——主线程

            当调用Qt::QueuedConnection时,槽函数在由其所在线程再次进入事件循环的时候调用——主线程

            Qt::AutoConnection,槽函数和发送信号同处一线程,相当于Qt::DirectConnection——主线程

            Qt::QueuedConnection:信号发送者和接收者不能在同一线程,造成死锁。

          要想让槽函数在其他线程中执行怎么做?那就在Thread的构造函数中添加一句

           this->moveToThread(this);

           然后在run中执行

           exec();

           解释:将对象移动到线程中(因为对象由主线程创建,归属主线程,需要移动),启动线程的事件循环——(不推荐这样做

 

  • 使用方法2时,不能绑定类的parent,否则会有如下警告 QObject::moveToThread: Cannot move objects with a parent,函数调用失败。
  • QWidget不能调用方法2
  • 方法2中的槽函数的执行必定是在调用目标线程的start()方法之后,所有一般执行完moveToThread方法后就调用线程的start方法,QThread的默认run方法如下,也就是线程进入了事件循环,开始处理消息:
    void QThread::run()
    {
        (void) exec();
    }

     

你可能感兴趣的:(Qt)