国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Qt】多線程QThread::run()與QObject::moveToThread()

這篇具有很好參考價值的文章主要介紹了【Qt】多線程QThread::run()與QObject::moveToThread()。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

官方鏈接QThread Class | Qt Core 5.15.14

使用QThread::run()

簡單來說就是繼承QThread類,并重寫run()函數(shù),這樣run()函數(shù)中的代碼就會運行在子線程中。

QThread對象管理著一個線程,并通過start函數(shù)啟動這個線程,線程要執(zhí)行的代碼都在run()里面,run()函數(shù)的進入和返回,就相當于子線程的啟動和結束。

但是run()函數(shù)何時返回呢?一般有三種情況:

  1. run中代碼走一遍就返回了。
  2. run中有while循環(huán),在循環(huán)中有退出循環(huán)的flag變量,由外部程序置位這個flag,使循環(huán)退出,從而返回。
  3. run中最后一行是事件循環(huán)exec(),即程序會卡在這一行:this->exec();這種情況需要調(diào)用exit()或者terminate()才能讓事件循環(huán)停下,從而讓run返回。

當run函數(shù)執(zhí)行完畢的時候,新線程也就結束了,并且發(fā)出finished()信號。

#ifndef SOMETHINGTHREAD_H
#define SOMETHINGTHREAD_H

#include <QThread>
#include <QObject>

class SomethingThread : public QThread
{
    Q_OBJECT
public:
    explicit SomethingThread(QObject *parent = nullptr);

    void run() override;//線程函數(shù)

private: signals:
    void resultReady(const QString result);//如果有線程計算結果返回,可以通過這種方式

};

#endif // SOMETHINGTHREAD_H
#include "somethingthread.h"
#include "qdebug.h"

SomethingThread::SomethingThread(QObject *parent)
    : QThread{parent}
{

}

void SomethingThread::run()
{
     for(int i=0;i<10;i++)
     {
         qDebug()<<"doing something %d"<<i<<" thread_id"<<QThread::currentThreadId();
         QThread::sleep(1);
     }
     emit this->resultReady("finish");//觸發(fā)信號,傳遞結果參數(shù)
}
    SomethingThread* sth=new SomethingThread(this);
    connect(sth,&SomethingThread::resultReady,this,&SIHToolBar::onResultReady);//使用接收結果
    connect(sth,&SomethingThread::finished,sth,&QObject::deleteLater);
    sth->start();


void SIHToolBar::onResultReady(const QString result)
{
    qDebug()<<"onResultReady result="<<result<<" thread_id="<<QThread::currentThreadId();
}
doing something %d 0  thread_id 0x6188
doing something %d 1  thread_id 0x6188
doing something %d 2  thread_id 0x6188
doing something %d 3  thread_id 0x6188
doing something %d 4  thread_id 0x6188
doing something %d 5  thread_id 0x6188
doing something %d 6  thread_id 0x6188
doing something %d 7  thread_id 0x6188
doing something %d 8  thread_id 0x6188
doing something %d 9  thread_id 0x6188
onResultReady result= "finish"  thread_id= 0x2f0

有幾點需要注意:

  • QThread類中的run()函數(shù)默認實現(xiàn)是這樣的QThread::run() { this->exec(); },也就是默認開啟了事件循環(huán)。
  • 只有run函數(shù)中的代碼段是在子線程中執(zhí)行的。如果run中使用了成員變量,而且其他地方也使用到了它,這時需要自行檢查是否線程安全。
  • run函數(shù)中發(fā)射的信號,連接了使用它的對象的槽函數(shù),實際上是跨線程了的。
  • 官方不推薦使用這種方式

使用QObject::moveToThread()

moveToThread 方法,是把我們需要的工作全部封裝在一個類中,將每個任務定義為一個槽函數(shù),再建立觸發(fā)這些槽函數(shù)的信號,然后連接信號和槽,最后調(diào)用 moveToThread 方法將這個類交給一個 QThread 對象,再調(diào)用 QThread 的 start() 函數(shù)使其全權處理事件循環(huán)。于是,任何時候我們需要讓子線程執(zhí)行某個任務,只需要發(fā)出對應的信號就可以。

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:
    void resultReady(const QString& result);//線程完成工作時發(fā)送的信號

public slots:
    void doWork(const QString& param);//定義了線程要執(zhí)行的操作

};

#endif // WORKER_H
#include "worker.h"
#include <QDebug>
#include <QThread>

Worker::Worker(QObject *parent)
    : QObject{parent}
{

}


void Worker::doWork(const QString &param)
{
    for(int i=0;i<10;i++)
    {
        qDebug()<<"doWork %d"<<i<<" thread_id"<<QThread::currentThreadId();
        QThread::sleep(1);
    }
    emit this->resultReady("finish");//觸發(fā)信號,傳遞結果參數(shù)
}
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QObject>
#include <QThread>
class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    explicit Controller(QObject *parent = nullptr);
    ~Controller();

signals:
    void doWork(const QString& param);//發(fā)送信號 觸發(fā)線程

public slots:
    void onResultReady(const QString& result);//處理子線程執(zhí)行的結果

};

#endif // CONTROLLER_H

#include "controller.h"
#include "worker.h"
#include <QDebug>
Controller::Controller(QObject *parent)
    : QObject{parent}
{
    Worker* work=new Worker();
    work->moveToThread(&this->workerThread);//調(diào)用moveToThread將該任務交給

    connect(&this->workerThread,&QThread::finished,work,&QObject::deleteLater);//當線程結束的時候,銷毀worker對象
    connect(this,&Controller::doWork,work,&Worker::doWork);//通過controller的dowork信號 連接 worker對象的doworker槽函數(shù)
    connect(work,&Worker::resultReady,this,&Controller::onResultReady);
    workerThread.start();

    qDebug()<<"main thread_id="<<QThread::currentThreadId();
    emit this->doWork("start");
    //work->doWork("start");//這種直接調(diào)用的方式?jīng)]有在子線程中執(zhí)行
}

Controller::~Controller()
{
    workerThread.quit();
    workerThread.wait();
}

void Controller::onResultReady(const QString &result)
{
    qDebug()<<"onResultReady result="<<result<<" thread_id="<<QThread::currentThreadId();
}
main thread_id= 0x7254
doWork %d 0  thread_id 0x5970
doWork %d 1  thread_id 0x5970
doWork %d 2  thread_id 0x5970
doWork %d 3  thread_id 0x5970
doWork %d 4  thread_id 0x5970
doWork %d 5  thread_id 0x5970
doWork %d 6  thread_id 0x5970
doWork %d 7  thread_id 0x5970
doWork %d 8  thread_id 0x5970
doWork %d 9  thread_id 0x5970
onResultReady result= "finish"  thread_id= 0x7254

有幾點需要注意:文章來源地址http://www.zghlxwxcb.cn/news/detail-475313.html

  • 任何對象只要執(zhí)行了moveToThread,那么該對象的所有槽函數(shù)就會在子線程執(zhí)行(前提是,該槽函數(shù)是被信號觸發(fā)的),如果直接顯示調(diào)用這些槽函數(shù),仍然會運行在原線程,不會出現(xiàn)多線程的效果。
  • 我們可以在一個worker類中定義多個需要做的工作(槽函數(shù)),然后觸發(fā)信號,子線程就可以執(zhí)行。

到了這里,關于【Qt】多線程QThread::run()與QObject::moveToThread()的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • QThread: Destroyed while thread is still running——線程正在運行時銷毀了線程

    QThread: Destroyed while thread is still running——線程正在運行時銷毀了線程 在編寫多線程程序時,可能會遇到“QThread: Destroyed while thread is still running”這個錯誤。這個錯誤表示在一個線程仍在運行時,它被銷毀了。 一個常見的情況是,當一個線程正在執(zhí)行某些操作時,它被強制銷

    2024年02月15日
    瀏覽(26)
  • QT學習之旅 - QThread多線程

    其實QT中的thread(線程)是很容易的 首先是主線程 其次是一個程序 通過一個QThread來放入程序 一個簡單的線程就實現(xiàn)了 進階一點: 手動開啟關閉線程 添加一個按鍵,通過 信號和槽 來控制線程使能關閉 Test不變。 現(xiàn)象 是 mainwindow i:99(執(zhí)行完) 后窗口出現(xiàn),之后 開啟線程 。開啟后

    2024年02月16日
    瀏覽(16)
  • C++ Qt開發(fā):運用QThread多線程組件

    C++ Qt開發(fā):運用QThread多線程組件

    Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹如何運用 QThread 組件實現(xiàn)多線程功能。 多線程技術在程序開發(fā)中尤為常用,Q

    2024年03月09日
    瀏覽(53)
  • QT中Qthread線程徹底銷毀的實例與注意事項(防止線程資源內(nèi)存泄露)

    ?注意: 釋放線程的時候觸發(fā)線程的信號與槽連接時的連接類型參數(shù)一定要是Qt::ConnectionType::DirectConnection, 否則線程銷毀不了會造成內(nèi)存泄露,通過任務欄開啟資源管理器可監(jiān)視cup的線程數(shù)變化情況。 QThread* th=new QThread(); ? ? ? ? ? Work* mywork=new Work (); ? ? ? ? ? mywork-move

    2024年02月02日
    瀏覽(23)
  • 記錄opencv的 QObject::moveToThread: Current thread(...) is not the object`s thread 錯誤

    記錄opencv的 QObject::moveToThread: Current thread(...) is not the object`s thread 錯誤

    這個錯誤主要是在qt庫的加載上,在安裝的opencv-python工具包下有個qt文件夾,這個文件夾里面的文件估計是要來加載qt的,要是這個里面的qt庫的版本和pip install pyqt5所使用的qt庫的版本一樣估計是沒什么問題,要是不一樣。就會出現(xiàn)核心轉(zhuǎn)移的錯誤。(這里為什么這么說,是因

    2024年02月12日
    瀏覽(17)
  • 【QT5-自我學習-線程qThread練習-兩種使用方式-1:通過繼承線程類來使用-基礎樣例】

    【QT5-自我學習-線程qThread練習-兩種使用方式-1:通過繼承線程類來使用-基礎樣例】

    學習線程其實有一段時間了,當時只是學習,沒有實際用起來,最近做的一個qt程序,發(fā)現(xiàn)如果不使用線程,那么就會導致界面卡死,這樣才體現(xiàn)出線程的實際作用。 發(fā)現(xiàn)卡頓的程序就是前幾天說到的“【QT調(diào)用ST-link-使用QT編寫程序-調(diào)用ST-LINK_CLI.exe-燒寫STM32F4xxx-基礎樣例】”

    2024年02月11日
    瀏覽(29)
  • 13-1_Qt 5.9 C++開發(fā)指南_多線程及QThread 創(chuàng)建多線程程序_ThreadSignal

    13-1_Qt 5.9 C++開發(fā)指南_多線程及QThread 創(chuàng)建多線程程序_ThreadSignal

    一個應用程序一般只有一個線程,一個線程內(nèi)的操作是順序執(zhí)行的,如果有某個比較消耗時間的計算或操作,比如網(wǎng)絡通信中的文件傳輸,在一個線程內(nèi)操作時,用戶界面就可能會凍結而不能及時響應。這種情況下,可以創(chuàng)建一個單獨的線程來執(zhí)行比較消耗時間的操作,并與

    2024年02月14日
    瀏覽(16)
  • Qt+C++多線程thread-QThread-QTimer視頻-控件動畫-混合應用實例

    Qt+C++多線程thread-QThread-QTimer視頻-控件動畫-混合應用實例

    程序示例精選 Qt+C++多線程thread-QThread-QTimer混合應用實例 如需安裝運行環(huán)境或遠程調(diào)試,見文章底部個人 QQ 名片,由專業(yè)技術人員遠程協(xié)助! 這篇博客針對Qt+C++多線程thread-QThread-QTimer混合應用實例編寫代碼,代碼整潔,規(guī)則,易讀。 學習與應用推薦首選。 功能:多線程thr

    2024年02月16日
    瀏覽(26)
  • QObject::moveToThread: Current thread(...) is not the object`s thread. Cannot move to target thread(

    最近在使用 conda 環(huán)境踩了個坑,運行 opencv 項目時彈出滿屏的 Qthread 報錯。 網(wǎng)上的解決方法大多是把 opencv-python 降級,或者 sudo 用包管理器安裝到系統(tǒng),但是都沒有很徹底或者說優(yōu)雅地解決問題。 問題描述 python 3.8 (conda) 環(huán)境下,運行 opencv 項目出現(xiàn)報錯:QObject::moveToThread

    2024年02月11日
    瀏覽(24)
  • qt之movetothread理解

    qt的下線程qthread,每個線程都有自己的事件循環(huán)exec。 對象的線程上下文,每個對象都有自己的線程上下文,怎么理解呢,就是該對象在哪個線程創(chuàng)建,其線程上下文就是誰。 每個qobject對象在創(chuàng)建時都有包含線程成員,threaddata,該成員的類型是QThreadData,該成員與qobject對象

    2024年02月09日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包