Qt Quick快速入門之線程基礎

  首先必須明確的是,Qt中的線程使用是相對複雜的,並不像C#中那麼隨意,特別是結合串口、網絡編程等,使用時稍有不慎就會出問題,而後Qt裏面常常出了問題就直接崩潰(這個真是誰用誰知道),因此若是在功能上用異步方式能作到其實就不必本身去開線程,固然若是本身寫的函數比較耗時(好比不斷地循環作操做之類的)就沒法避免使用線程了。編程

  Qt中通常將耗時操做單獨放在一個類中實現,在主線程中建立類對象,而後將這個對象移到子線程中,主線程與子線程間的通訊主要經過信號和槽實現。另外對象是在主線程中建立的,對象中的成員都屬於主線程,在主、子線程中均可以直接訪問,不過若是你把對象中的成員也移到子線程中,那麼在主線程就不能直接訪問這個成員了。網絡

  下面是一個使用實例。異步

class ThreadManager : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    ThreadManager();
    ~ThreadManager();
    MyWorker * worker;
signals:
    void start();
public slots:
    void emitstart();
    void emitstop();

    void printThreadId(int count);
};
ThreadManager::ThreadManager()
{
    worker = new MyWorker();
    worker->moveToThread(&workerThread);
    connect(this,SIGNAL(start()),worker,SLOT(Start()));
    connect(worker,SIGNAL(invokeParentThreadMethod(int)),this,SLOT(printThreadId(int)));
    workerThread.start();
}

ThreadManager::~ThreadManager()
{
    workerThread.quit();
}

void ThreadManager::emitstart()
{
    emit start();
}

void ThreadManager::emitstop()
{
    worker->stoped = true;
    qDebug()<<"中止";
}

void ThreadManager::printThreadId(int count)
{
    //worker->stoped = true;
    qDebug()<<QThread::currentThreadId()<<"\t"<<count;
}

ThreadManager 用來開啓一個新的線程,而後在這個線程裏面執行其餘操做,下面是執行操做的類 MyWorker。函數

 

class MyWorker : public QObject
{
    Q_OBJECT
public:
    explicit MyWorker(QObject *parent = 0);
    bool stoped;
signals:
    void invokeParentThreadMethod(int count);
public slots:
    void Start();
};
MyWorker::MyWorker(QObject *parent) :
    QObject(parent)
{
    stoped = false;
}

void MyWorker::Start()
{
    int count =0;
    stoped = false;
    while(!stoped)
    {
        qDebug()<<QThread::currentThreadId()<<"\t"<<count++;
        emit invokeParentThreadMethod(count);
        QThread::msleep(500);
    }
}


再看看咱們在主線程中如何使用的ui

    QObject* win = engine.rootObjects()[0];
    QObject* Button_Start = win->findChild<QObject*>("Button_Start");
    QObject* Button_Stop = win->findChild<QObject*>("Button_Stop");

    ThreadManager* therad = new ThreadManager();
    QObject::connect(Button_Start,SIGNAL(clicked()),therad,SLOT(emitstart()));
    QObject::connect(Button_Stop,SIGNAL(clicked()),therad,SLOT(emitstop()));

這裏只是一個很簡單的線程使用示例,在串口、網絡編程時每每涉及到線程同步、資源共享、線程通訊等問題,好比子線程還在使用資源主線程卻將資源釋放了或是線程間通訊時傳過去的數據發生了變化等等,具體狀況只有結合本身經驗去分析了。this

相關文章
相關標籤/搜索