《完美Qt》之線程調用定時器

在線程中調用定時器

嗨,大家好,我們都知道無論線程和定時器,這兩個單獨使用都非常簡單,Qt幫助文檔有很詳細的Demo。但是在線程中使用定時器就稍微有點麻煩了,一不注意就容易掉坑裏。

首先理解connect的第五個參數很重要—連接類型

1、connect的第五個參數介紹

Qt::AutoConnection
(Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
Qt::DirectConnection
The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
Qt::QueuedConnection
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Qt::BlockingQueuedConnection
Same as Qt::QueuedConnection, except that the signalling thread blocks until the slot returns. This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
Qt::UniqueConnection
This is a flag that can be combined with any one of the above connection types, using a bitwise OR. When Qt::UniqueConnection is set, QObject::connect() will fail if the connection already exists (i.e. if the same signal is already connected to the same slot for the same pair of objects). This flag was introduced in Qt 4.6.

2、子線程類

    #ifndef CTHREAD_H
    #define CTHREAD_H

    #include <QThread>
    #include <QTimer>
    #include <QDebug>
    class CThread : public QThread
    {
        Q_OBJECT
    public:
        explicit CThread(QObject *parent = 0);
    protected:
        void run()
        {
            m_timer = new QTimer; //new QTimer(this);
                                   //在這個線程創建的對象,這個對象就屬於這個線程,如果指定父對象,這個對象就在父對象的線程
            connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()), Qt::DirectConnection);
                                    //指定連接方式爲DirectConnection,那麼槽函數就在信號的發送者的線程內執行,
                                    //如果指定爲QueuedConnection,那麼就在槽函數就在槽函數的對象執行。
                                    //這裏的定時器是在子線程裏創建的,所以該對象是子線程對象,CThread實例是在main裏創建的,所以這裏的槽函數默認屬於主線程
            m_timer->start(1000);
            this->exec();
        }
    signals:

    public slots:
        void onTimeout()
        {
            //打印線程id
            qDebug() << "sub thread id: " << QThread::currentThreadId();
        }
    private:
        QTimer *m_timer;
    };

    #endif // CTHREAD_H

3、main函數

    #include "widget.h"
    #include <QApplication>
    #include "cthread.h"
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);

        //C打印主線程id號
        qDebug() << "main thread id: " << QThread::currentThreadId();

        CThread thread;
        thread.start(); //啓動子線程

        return a.exec();
    }

4、輸出

main thread id:  0x51c
sub thread id:  0x1c38
sub thread id:  0x1c38
sub thread id:  0x1c38
sub thread id:  0x1c38

4、參考

下面給出繼承QThread實現的參考地址
http://jingyan.baidu.com/article/ed15cb1bbbe05f1be36981ba.html

當然也可以使用movetoThread的方法
http://blog.csdn.net/zgrjkflmkyc/article/details/41381327?locationNum=4&fps=1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章