QThread的使用总结(2)

    根据QT的asstant的描述,moveToThread的作用是把一个 QOject移动到一个线程里面去,那么它到底是什么意思呢。我的理解就是当我们调用QObject的moveToThread方法之后,我们这个派生自 QObject的类的代码就会在新的线程里面执行。而那篇文章所说的就是大多数对这个函数产生了误解,人们总是在派生的QThread的类的构造函数里面 调用moveToThread(this)以希望把该类的所有函数都在该线程里面执行。这样是错误的。
include   
include   
include   

class MyObject : public QObject 
{  
    Q_OBJECT  
    public:  
    MyObject() {};  
    ~MyObject() {}  
    
    public slots:  
    void first() {  
        qDebug() << QThread::currentThreadId();  
    }  
    void second() {  
        qDebug() << QThread::currentThreadId();  
    }  
    void three() {  
        qDebug() << QThread::currentThreadId();  
    }  
};  

#include "mainwindow.h"  
#include   
#include   
#include "myobject.h"  

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) 
{  
    my = new MyObject;  
    firstButton = new QPushButton(tr("first"), 0);  
    connect(firstButton, SIGNAL(clicked()), my, SLOT(first()), Qt::QueuedConnection);  
    secondButton = new QPushButton(tr("second"), 0);  
    connect(secondButton, SIGNAL(clicked()), my, SLOT(second()), Qt::QueuedConnection);  
    threeButton = new QPushButton(tr("three"), 0);  
    connect(threeButton, SIGNAL(clicked()), my, SLOT(three()), Qt::QueuedConnection);  
    selfButton = new QPushButton(tr("self"), 0);  
    connect(selfButton, SIGNAL(clicked()), this, SLOT(onSelfPushed()));  
    exitButton = new QPushButton(tr("exit"), 0);  
    connect(exitButton, SIGNAL(clicked()), this, SLOT(onExitPushed()));  
    
    QVBoxLayout *layout = new QVBoxLayout;  
    layout->addWidget(firstButton);  
    layout->addWidget(secondButton);  
    layout->addWidget(threeButton);  
    layout->addWidget(selfButton);  
    layout->addWidget(exitButton);  
    
    QWidget *p = new QWidget;  
    p->setLayout(layout);  
    
    QThread *thread = new QThread;  
    my->moveToThread(thread);  
    
    thread->start();  
    connect(thread, SIGNAL(started()), my, SLOT(first()));  
    
    setCentralWidget(p);  
}  

MainWindow::~MainWindow() {  
}  

void MainWindow::onFirstPushed() {  
    my->first();  
}  

void MainWindow::onSecondPushed() {  
    my->second();  
}  

void MainWindow::onThreePushed() {  
    my->three();  
}  

void MainWindow::onSelfPushed() {  
    qDebug() << QThread::currentThreadId();  
}  

void MainWindow::onExitPushed() {  
    close();  
}  
   通过测试,在mainwidow.cxx使用上面的代码的时候,由于my调用了movetothread函数,那么它所有的槽函数都是执行在新开辟的线程里面。
   如果去掉moveToThread函数,那么所有的函数都将执行在gui线程里面。
   同时为了测试connect的第五个参数,在connect的时候可以将Qt::QueuedConnection修改为Qt::DirectConnection,这样所有的槽函数也将在主线程里面执行。
   最后要注意的是,如果上面connect的时候连接的是this的onXXXXXX槽函数再来调用的my的槽函数的话,那么这些槽函数也将执行在onXXXXX槽函数所在的线程,这里是主线程。
   通过上面的测试,我们在使用线程的时候,就可以将一个类派生自QObject,然后实现所有的signal/slot,然后通过调用 movetothread函数来使他们执行在新的线程里面,而不是每次都要重新派生QThread,并且派生QThread函数的另外一个不好的地方是只 有run函数内部的代码才会执行在新线程里面,相比起来,派生QObject并使用movetothread函数更具有灵活性。
 

你可能感兴趣的:(Qt)