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

The fifth parameter of the qt slot function(qt Connect函數(shù)的第五個(gè)參數(shù))

這篇具有很好參考價(jià)值的文章主要介紹了The fifth parameter of the qt slot function(qt Connect函數(shù)的第五個(gè)參數(shù))。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

preface(前言)

在Qt中,信號(hào)槽機(jī)制是允許對(duì)象之間通信的核心特性。
在處理線程時(shí),非常必要了解信號(hào)和插槽在多線程環(huán)境中的工作方式。
關(guān)于connect函數(shù)的“第五個(gè)參數(shù)”,指的是connect()方法中的Qt::ConnectionType參數(shù)。此參數(shù)確定連接的類型,這在多線程應(yīng)用程序中非常重要。

qt Connect函數(shù)的第五個(gè)參數(shù)(這里專門(mén)指:QueuedConnection)-多線程編程的一些原理

1)初步理解

現(xiàn)在讓我們通過(guò)一個(gè)例子深入研究Qt的信號(hào)槽機(jī)制中的連接連接的概念,我將引導(dǎo)你理解它的工作原理。


假設(shè)在一個(gè)Qt應(yīng)用程序中有兩個(gè)線程:線程A和線程B。線程A是主GUI線程,而線程B是后臺(tái)工作線程。你希望線程B在完成任務(wù)時(shí)通知線程A,因此你將使用Qt的信號(hào)槽機(jī)制來(lái)實(shí)現(xiàn)這一點(diǎn)。
典型的直接連接(單線程應(yīng)用程序的默認(rèn)設(shè)置)中,當(dāng)發(fā)出信號(hào)時(shí),插槽立即執(zhí)行。但是,在多線程方案中,這種立即執(zhí)行可能不安全或不可行,因?yàn)榭赡苄枰?code>插槽來(lái)操作GUI組件或訪問(wèn)僅可從主線程安全訪問(wèn)的資源。
這就是連接的作用。
使用QueuedConnection,當(dāng)線程B發(fā)出信號(hào)時(shí),該信號(hào)被放置在線程A事件隊(duì)列中,所以不會(huì)立即執(zhí)行。然后,當(dāng)線程A事件循環(huán)下一次被處理時(shí),它在隊(duì)列中檢測(cè)到這個(gè)信號(hào),并執(zhí)行相應(yīng)的slot函數(shù)。這樣,即使信號(hào)是從不同的線程發(fā)出的,slot函數(shù)也會(huì)在接收對(duì)象所在的線程中安全地執(zhí)行,從而防止任何線程安全問(wèn)題。

2)加深理解

為了幫助鞏固這一概念,你能想到一個(gè)簡(jiǎn)單的場(chǎng)景,在這種類型的連接是必要的嗎?

例如,假設(shè)線程B正在執(zhí)行文件下載,您希望在完成此下載后更新GUI(線程A)中的進(jìn)度條。在這種情況下,您將如何設(shè)置信號(hào)和插槽,使用一個(gè)連接?

現(xiàn)在請(qǐng)關(guān)閉博客,給你5分鐘來(lái)思考…

two thousand years later…

下面具體展開(kāi)來(lái)講講:
我可以使用QueuedConnection將線程AB進(jìn)行連接,線程B邊下載邊計(jì)算 已下載/總文件大小,分別在10%,20%,30%...100%向線程A發(fā)送一個(gè)信號(hào),該信號(hào)的參數(shù)就是下載的百分比,然后線程A收到后,根據(jù)線程B的參數(shù)來(lái)更新GUI

demo

在寫(xiě)demo之前,我有一個(gè)疑問(wèn)?qt的connect函數(shù)是同步的還是異步的?

Q t Qt Qt c o n n e c t connect connect 函數(shù)用于將信號(hào)與槽連接起來(lái),但它本身既不是同步的也不是異步的。這個(gè)函數(shù)的作用是建立一個(gè)連接,當(dāng)信號(hào)發(fā)生時(shí),相應(yīng)的槽函數(shù)會(huì)被調(diào)用。

關(guān)于同步異步的行為,這取決于信號(hào)槽函數(shù)的執(zhí)行方式,而不是 connect 函數(shù)本身。

在 Qt 中,

  • 如果信號(hào)和槽都在同一個(gè)線程中,槽函數(shù)的調(diào)用通常是同步的,即在信號(hào)發(fā)射后立即執(zhí)行。
  • 如果信號(hào)和槽位于不同的線程,Qt 使用消息隊(duì)列來(lái)傳遞信號(hào),這時(shí)槽函數(shù)的調(diào)用是異步的,會(huì)在目標(biāo)線程的事件循環(huán)中稍后執(zhí)行。

因此,connect 函數(shù)的作用是建立信號(hào)和槽之間的連接,而信號(hào)到槽的調(diào)用機(jī)制決定了同步或異步行為。

單線程

實(shí)現(xiàn)邊下載某個(gè)網(wǎng)頁(yè)的文件,邊實(shí)時(shí)更新當(dāng)前的進(jìn)度條

#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QProgressBar>
#include <QFile>
#include <QUrl>

class Downloader : public QObject
{
    Q_OBJECT

public:
    Downloader(const QUrl& url, QProgressBar* progressBar, QObject* parent = nullptr)
        : QObject(parent), url(url), progressBar(progressBar)
    {
    	//這一行代碼僅僅是創(chuàng)建了一個(gè) QNetworkAccessManager 的實(shí)例,并將其分配給 manager 指針。這一行代碼本身并沒(méi)有建立連接或發(fā)起網(wǎng)絡(luò)請(qǐng)求。
        manager = new QNetworkAccessManager(this);
        //當(dāng)網(wǎng)絡(luò)請(qǐng)求完成或下載進(jìn)度發(fā)生變化時(shí),相關(guān)的槽函數(shù)將被調(diào)用。
        //即,下載完成后,會(huì)執(zhí)行onFinished函數(shù)進(jìn)行收尾工作
        connect(manager, &QNetworkAccessManager::finished, this, &Downloader::onFinished);
    }

    void startDownload()
    {
        reply = manager->get(QNetworkRequest(url));//這句話是異步的,并不會(huì)阻塞
        //當(dāng)下載進(jìn)度發(fā)生變化時(shí),相關(guān)的槽函數(shù)將被調(diào)用。
        connect(reply, &QNetworkReply::downloadProgress, this, &Downloader::onDownloadProgress);
    }

private slots:
    void onFinished(QNetworkReply* reply)
    {
        if (reply->error() == QNetworkReply::NoError)//下載很順利,沒(méi)有錯(cuò)誤
        {
            // 下載完成
            QByteArray data = reply->readAll();
            // 處理下載的數(shù)據(jù)
            //to do ...
            //eg:將下載文件解壓、對(duì)比、等等

            // 清理資源
            reply->deleteLater();
            manager->deleteLater();
        }
        else
        {
            // 處理下載錯(cuò)誤
            //搞個(gè)QMessageBox提示框報(bào)錯(cuò)
        }
    }

	//當(dāng)下載進(jìn)度發(fā)生變化時(shí),相關(guān)的槽函數(shù)將被調(diào)用。
    void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    {
        // 更新進(jìn)度條
        int progress = static_cast<int>(bytesReceived * 100 / bytesTotal);
        progressBar->setValue(progress);
    }

private:
    QNetworkAccessManager* manager;
    QNetworkReply* reply;
    QUrl url;
    QProgressBar* progressBar;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 創(chuàng)建主窗口
    QWidget mainWindow;
    mainWindow.setWindowTitle("下載并更新進(jìn)度條示例");

    // 創(chuàng)建進(jìn)度條
    QProgressBar progressBar(&mainWindow);
    progressBar.setGeometry(10, 10, 280, 30);

    // 下載文件的URL
    QUrl downloadUrl("https://example.com/examplefile.txt");

    // 創(chuàng)建Downloader實(shí)例并開(kāi)始下載
    Downloader downloader(downloadUrl, &progressBar);//實(shí)例
    downloader.startDownload();//下載

    // 顯示主窗口
    mainWindow.show();

    return a.exec();
}

#include "main.moc"

解析

因?yàn)?reply = manager->get(QNetworkRequest(url));是異步的,,因?yàn)槭菃尉€程,所以connect函數(shù)是同步的(即在信號(hào)發(fā)射后立即執(zhí)行).

使用了 Qt 的 QNetworkAccessManager 和 QNetworkReply 來(lái)處理網(wǎng)絡(luò)下載,并且更新了 GUI 的 QProgressBar 來(lái)顯示下載進(jìn)度。這個(gè)設(shè)計(jì)考慮到了 Qt 的事件驅(qū)動(dòng)和異步處理機(jī)制,因此在理論上,GUI 不應(yīng)該在下載過(guò)程中出現(xiàn)卡頓。

  • 下面是關(guān)于代碼中的幾個(gè)關(guān)鍵點(diǎn)的解釋:
  1. 異步網(wǎng)絡(luò)請(qǐng)求:使用 QNetworkAccessManager 的 get 方法來(lái)發(fā)起網(wǎng)絡(luò)請(qǐng)求是異步的。這意味著 get 方法會(huì)立即返回,而不會(huì)等待下載完成。下載在后臺(tái)進(jìn)行,不會(huì)阻塞主線程

  2. 信號(hào)和槽機(jī)制:當(dāng)下載進(jìn)度更新或下載完成時(shí),將觸發(fā)信號(hào),如 downloadProgress 和 finished。這些信號(hào)連接到槽函數(shù) onDownloadProgress 和 onFinished,它們會(huì)在主線程中被調(diào)用,但由于它們的執(zhí)行時(shí)間通常很短,不太可能導(dǎo)致 GUI 卡頓

  3. GUI更新:進(jìn)度條的更新發(fā)生在 onDownloadProgress 槽中,這個(gè)操作通常很快,不會(huì)對(duì) GUI 性能產(chǎn)生顯著影響

綜上所述,如果下載任務(wù)和數(shù)據(jù)處理不是特別重或復(fù)雜,這個(gè)設(shè)計(jì)通常不會(huì)導(dǎo)致 GUI 卡頓。但是,如果在 onFinished 槽中的數(shù)據(jù)處理非常繁重(例如,處理非常大的文件或進(jìn)行復(fù)雜的數(shù)據(jù)操作),那么可能會(huì)影響 GUI 的響應(yīng)性。在這種情況下,可以考慮將數(shù)據(jù)處理任務(wù)移到另一個(gè)線程中去,以保持 GUI 的流暢性。

多線程

GUI:主線程A
下載的任務(wù):線程B
線程B在下載的同時(shí),會(huì)給計(jì)算下載的百分比,并將百分比發(fā)送給線程A文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-811567.html

#include <QThread>
#include <QObject>
#include <QDebug>
#include <...>

class Downloader : public QObject {
    Q_OBJECT

private:
	QNetworkAccessManager* manager;
    QNetworkReply* reply;
    QUrl url;
public slots:
    void download(QString Url) {// 六

		manager = new QNetworkAccessManager(this);
        connect(manager, &QNetworkAccessManager::finished, this, &Downloader::onFinished);
        reply = manager->get(QNetworkRequest(url));
        connect(reply, &QNetworkReply::downloadProgress, this, &Downloader::onDownloadProgress);
    	
    	/*
        for (int downloaded = 10; downloaded <= totalSize; downloaded += 10) {
            QThread::msleep(100);  // 模擬下載過(guò)程, 使用msleep代替sleep以增加進(jìn)度更新的頻率
            int percent = static_cast<int>(100.0 * downloaded / totalSize);
            emit progress(percent);
        }
        emit finished();
        */
    }
	void onFinished(QNetworkReply* reply)
    {
        emit finished(reply);
    }
    void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    {
        int progress = static_cast<int>(bytesReceived * 100 / bytesTotal);
        emit progress(progress);
    }

signals:
    void progress(int percent);
    void finished();
};



/
class MyWidget : public QObject {
    Q_OBJECT

public:
    MyWidget() {// 二
        // 將下載器移至工作線程
        downloader.moveToThread(&workerThread);

        // 連接開(kāi)始下載的信號(hào)到下載器的下載槽// 五
        connect(this, &MyWidget::startDownload, &downloader, &Downloader::download, Qt::QueuedConnection);

        // 連接下載器的進(jìn)度信號(hào)到處理進(jìn)度的槽
        connect(&downloader, &Downloader::progress, this, &MyWidget::handleProgress, Qt::QueuedConnection);

        // 連接下載完成信號(hào)
        connect(&downloader, &Downloader::finished, this, &MyWidget::handleFinished, Qt::QueuedConnection);

        // 啟動(dòng)工作線程
        workerThread.start();
    }

    ~MyWidget() {
        workerThread.quit();
        workerThread.wait();
    }

    void startDownloading(QString Url) {// 四
        emit startDownload(Url);  // 發(fā)送信號(hào)來(lái)開(kāi)始下載
    }

public slots:
    void handleProgress(int percent) {
        qDebug() << "Download progress:" << percent << "%";
        // 這里可以更新 GUI 進(jìn)度條
    }

    void handleFinished(QNetworkReply* reply) {
        if (reply->error() == QNetworkReply::NoError)//下載很順利,沒(méi)有錯(cuò)誤
        {
        	qDebug() << "Download finished!";
        	// 處理下載完成事件,例如關(guān)閉進(jìn)度條、彈出通知等操作
        	
            // 下載完成
            QByteArray data = reply->readAll();
            // 處理下載的數(shù)據(jù)
            //to do ...
            //eg:將下載文件解壓、對(duì)比、等等

            // 清理資源
            reply->deleteLater();
            manager->deleteLater();
        }
        else
        {
            // 處理下載錯(cuò)誤
            //搞個(gè)QMessageBox提示框報(bào)錯(cuò)
        }
    }

signals:
    void startDownload(int totalSize);

private:
    QThread workerThread;
    Downloader downloader;
};

#include "main.moc"

int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);
    
    MyWidget widget;// 一
    QString Url = "https://example.com/examplefile.txt";
    widget.startDownloading(Url);  // 三

    return app.exec();
}

解析

// 連接開(kāi)始下載的信號(hào)到下載器的下載槽
connect(this, &MyWidget::startDownload, &downloader, &Downloader::download, Qt::QueuedConnection);

// 連接下載器的進(jìn)度信號(hào)到處理進(jìn)度的槽
connect(&downloader, &Downloader::progress, this, &MyWidget::handleProgress, Qt::QueuedConnection);

// 連接下載完成信號(hào)
connect(&downloader, &Downloader::finished, this, &MyWidget::handleFinished, Qt::QueuedConnection);

附件

  1. 分別實(shí)現(xiàn)單線程與多線程下,qt下載文件并實(shí)時(shí)更新進(jìn)度條的流程圖

到了這里,關(guān)于The fifth parameter of the qt slot function(qt Connect函數(shù)的第五個(gè)參數(shù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Qt中實(shí)現(xiàn)界面回放的藝術(shù):從理論到代碼“ (“The Art of Implementing UI Playback in Qt: From Theory to Code

    Qt中實(shí)現(xiàn)界面回放的藝術(shù):從理論到代碼“ (“The Art of Implementing UI Playback in Qt: From Theory to Code

    在這個(gè)快速發(fā)展的數(shù)字化時(shí)代,界面回放技術(shù)(UI Playback Technology)在軟件開(kāi)發(fā)中扮演了至關(guān)重要的角色。這項(xiàng)技術(shù)不僅提高了軟件測(cè)試的效率,還為用戶交互設(shè)計(jì)提供了深刻的洞察。通過(guò)回放用戶與界面的交互過(guò)程,開(kāi)發(fā)者能夠更好地理解用戶行為,優(yōu)化用戶體驗(yàn)。正如計(jì)算

    2024年01月20日
    瀏覽(19)
  • Qt 多線程、信號(hào)和槽連接方式推薦connect(Sender,Singnal,Receiver,Slot,ConnectMode);如下圖所示

    Qt 多線程、信號(hào)和槽連接方式推薦connect(Sender,Singnal,Receiver,Slot,ConnectMode);如下圖所示

    connect(主線程A,信號(hào)A,子線程B,槽函數(shù)B,DirectConnection /AutoConnection?); connect(子線B,信號(hào)B,主線程A,槽函數(shù)A,QueueConnection??);

    2024年02月13日
    瀏覽(29)
  • MyBatis使用報(bào)錯(cuò)原因及解決辦法 ##The error occurred while setting parameters

    MyBatis使用報(bào)錯(cuò)原因及解決辦法 ##The error occurred while setting parameters

    The error occurred while setting parameters, MyBatis框架使用報(bào)錯(cuò)原因及解決辦法 編輯了多層查詢語(yǔ)句,在navicat運(yùn)行正常,但測(cè)試環(huán)境報(bào)錯(cuò) 懷疑是語(yǔ)句問(wèn)題,更改了查詢語(yǔ)句,還是不行 ** 這里原來(lái)rank是,要加` 才行** 部分

    2024年02月13日
    瀏覽(27)
  • NotImplementedError: Module is missing the required “forward“ function

    NotImplementedError: Module is missing the required “forward“ function

    在做中文文本情感分析model類定義的時(shí)候報(bào)錯(cuò)如下: 有兩種可能: 1.重寫(xiě)父類函數(shù)時(shí),函數(shù)名稱寫(xiě)錯(cuò),我將寫(xiě)成了?最終導(dǎo)致程序報(bào)錯(cuò): 2.def forward函數(shù)與def __init__(self,config):一定要對(duì)齊。

    2024年02月14日
    瀏覽(22)
  • QT錯(cuò)誤提示:Slots named on_foo_bar are error prone [clazy-connect-by-name]

    這個(gè)錯(cuò)誤提示來(lái)自Clazy,它是一個(gè)用于對(duì)Qt代碼進(jìn)行靜態(tài)分析的工具。錯(cuò)誤提示 “Slots named on_foo_bar are error prone [clazy-connect-by-name]” 意味著您的槽函數(shù)命名為\\\"on_foo_bar\\\",并且Clazy認(rèn)為這種命名方式容易引起錯(cuò)誤。 Clazy建議在使用Qt的信號(hào)槽連接時(shí),使用明確的命名約定,而不是

    2024年01月22日
    瀏覽(23)
  • error: (-2:Unspecified error) The function is not implemented.

    error: (-2:Unspecified error) The function is not implemented.

    一.環(huán)境配置 windows10+pycharm+python3.9 二、問(wèn)題描述 三、解決方法 1.pip安裝opencv-contrib-python,注意opencv-contrib-python版本和opencv版本要一致 分別運(yùn)行以下命令: 卸載opencv-python-headless: 更新opencv版本: 四.解決啦

    2024年02月08日
    瀏覽(29)
  • The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support

    The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support

    ros2 foxy 運(yùn)行單目orb slam3 編譯正常,程序運(yùn)行時(shí)報(bào)錯(cuò)如下 Loading ORB Vocabulary. This could take a while... Vocabulary loaded! Initialization of Atlas from scratch Creation of new map with id: 0 Creation of new map with last KF id: 0 Seq. Name: There are 1 cameras in the atlas Camera 0 is pinhole slam changed ============================ te

    2024年02月12日
    瀏覽(20)
  • 【warning】UserWarning: The parameter ‘pretrained‘ is deprecated since 0.13 and may be removed

    【warning】UserWarning: The parameter ‘pretrained‘ is deprecated since 0.13 and may be removed

    報(bào)錯(cuò)內(nèi)容: 翻譯一下,就是參數(shù)列表中的pretrained在新版本中被棄了,要使用weights這個(gè)參數(shù)。然后教你用新的參數(shù)。 就按照watning里寫(xiě)的把models.resnet101()后面的內(nèi)容重新設(shè)置就好。 第一種:weights = models.ResNet101_Weights.DEFAULT 輸出結(jié)果:? 第二種:weights = models.ResNet101_Weights.IMA

    2024年02月13日
    瀏覽(20)
  • 【Spring循環(huán)依賴的解決】The dependencies of some of the beans in the application context form a cycle

    【Spring循環(huán)依賴的解決】The dependencies of some of the beans in the application context form a cycle

    啟動(dòng)報(bào)錯(cuò): The dependencies of some of the beans in the application context form a cycle: 兩個(gè)類相互引用對(duì)方,導(dǎo)致Spring在初始化bean的時(shí)候不知道先初始化哪個(gè),從而形成循環(huán)依賴注入。 類A依賴類B,類B也依賴類A,這種情況就會(huì)出現(xiàn)循環(huán)依賴。 Bean A → Bean B → Bean A 上面是比較容易發(fā)現(xiàn)的

    2024年02月08日
    瀏覽(30)
  • 【Spring循環(huán)依賴報(bào)錯(cuò)】The dependencies of some of the beans in the application context form a cycle

    ???????類A需要通過(guò)構(gòu)造函數(shù)注入的類B的實(shí)例(或者B中聲明的Bean),而類B需要通過(guò)構(gòu)造函數(shù)注入的類A的實(shí)例(或者A中聲明的Bean),導(dǎo)致循環(huán)依賴注入。 其中一個(gè)不要引用對(duì)方,避免循環(huán)依賴,代碼解耦肯定是最優(yōu)解。 選擇其中一個(gè)使用@Lazy 注解。 ???????延遲互相

    2024年02月07日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包