最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt多線程安全更新QLabel的實現(xiàn)

 更新時間:2026年02月08日 11:53:44   作者:Matsuko  
本文主要介紹了Qt多線程安全更新QLabel的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

背景——在 Qt 應(yīng)用程序中渲染視頻時,一個常見的需求是將每一幀更新到 QLabel 控件中顯示。但是,當(dāng)渲染線程不在主線程時,直接更新UI可能會導(dǎo)致程序崩潰。

解析視頻數(shù)據(jù)

處理原始字節(jié)數(shù)組

對于RGBA格式的原始字節(jié)數(shù)組,可以直接創(chuàng)建QImage:

    QImage image(frame, width, height, width * 4, QImage::Format_RGBA8888);
    image = image.scaled(label->width(), label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);

處理YUV數(shù)據(jù)

對于YUV格式的數(shù)據(jù),需要先獲取Y、U、V分量的buffer和pitch(步長):

    uint8_t *i420_buffer[3];
    int pitch[3];
    i420_buffer[0] = frame->GetBufferY();
    i420_buffer[1] = frame->GetBufferU();
    i420_buffer[2] =frame->GetBufferV();
    pitch[0] = frame->GetPitch0();
    pitch[1] = frame->GetPitch1();
    pitch[2] = frame->GetPitch2();

i420_buffer 數(shù)組和 pitch 數(shù)組分別包含了YUV幀的數(shù)據(jù)和每行的字節(jié)數(shù)(也稱為步長)。i420_buffer[0],i420_buffer[1] 和i420_buffer[2]分別包含了Y,U和V的數(shù)據(jù)。pitch[0],pitch[1]和pitch[2]分別是Y,U和V的步長。然后我們就可以使用這些數(shù)據(jù)和步長來訪問YUV幀的每個像素:

  • 訪問第y行第x列的Y值:
    uint8_t Y = i420_buffer[0][y * pitch[0] + x];
  • 訪問第y行第x列的U和V值:
    uint8_t U = i420_buffer[1][(y/2)* pitch[1]+(x / 2)];
    uint8_t V = i420_buffer[2][(y/2)* pitch[2]+(x / 2)];

(U和V的數(shù)據(jù)是以2x2的塊存儲的,所以需要除以2來獲取正確的索引。)

YUV到RGB的轉(zhuǎn)換可以通過以下公式進行:

R = Y + 1.402 * (V - 128)
G = Y - 0.344 * (U - 128) - 0.714 * (V - 128)
B = Y + 1.772 * (U - 128)
for(int y = 0; y < height; ++y){
    for(int x = 0; x < width; ++x){
        uint8_t Y = i420 buffer[0][y * pitch[0] + x];
        uint8_t U = i420 buffer[1][(y / 2) * pitch[1] + (x / 2)];
        uint8_t V = i420 buffer[2][(y / 2) * pitch[2] + (x / 2)];
        int R = Y + 1.402 * (V - 128);
        int G = Y - 0,344 * (U - 128) - 0.714 * (V - 128);
        int B = Y + 1.772 * (U -128);
        image.setPixelColor(x,y,QColor(qBound(0, R, 255), qBound(0, G, 255), qBound(0, B, 255)));
    }
}

但是?。。?/p>

使用 setPixelColor 效率太低啦,一不小心還會收到 Qt Creator 的小提醒 ????:

The cached device pixel ratio value was stale on window expose. Please file a QTBUG which explains how to reproduce.

我們有更好用的工具:libyuv

    libyuv::I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, stc_stride_v, argb_buffer, width * 4, width, height);

安全地渲染到QLabel

如果渲染視頻的線程是主線程,我們可以在得到 QImage 之后直接設(shè)置到 QLabel :

    label->setPixmap(QPixmap::fromImage(image));

但是如果我們是在回調(diào)函數(shù)中解析幀數(shù)據(jù)并更新(也就是在非主線程中更新UI組件),那就可能會導(dǎo)致崩潰或其他不穩(wěn)定行為啦。Qt 的 GUI 組件不是線程安全的,這意味著我們只能在主線程中對它們進行操作。

可以使用信號和槽機制將圖像傳遞回主線程:在非主線程中處理圖像并通過信號發(fā)送圖像數(shù)據(jù),在主線程中接收信號并更新QLabel。

// 在非主線程中
void  processImage() {
    // 將數(shù)據(jù)轉(zhuǎn)換為QImage

    emit imageProcessed(image);
}

// 在主線程中
void renderImage(const QImage& image) {
    // ……

    label->setPixmap(QPixmap::fromImage(image));
}

還有一種更巧妙的寫法(參考 Qt Forum 討論 ):

    QTimer::singleShot(0, this, [this, pixmap](){
        ui->label->setPixmap(pixmap);
        ui->label->setScaledContents(true);
        ui->label->show();
    });

這種方法會在主事件循環(huán)的下一個時間點執(zhí)行更新操作,從而確保在主線程中安全地更新UI。

總結(jié)

通過以上方法,我們可以在多線程環(huán)境下安全高效地將視頻幀渲染到QLabel控件中,避免程序崩潰等問題。

到此這篇關(guān)于Qt多線程安全更新QLabel的實現(xiàn)的文章就介紹到這了,更多相關(guān)Qt 安全更新QLabel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于C語言實現(xiàn)的迷宮游戲代碼

    基于C語言實現(xiàn)的迷宮游戲代碼

    這篇文章主要介紹了基于C語言實現(xiàn)的迷宮游戲代碼,對于學(xué)習(xí)游戲開發(fā)的朋友相信有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • 老程序員教你一天時間完成C語言掃雷游戲

    老程序員教你一天時間完成C語言掃雷游戲

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)掃雷游戲初級版,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 基于Qt實現(xiàn)的自定義樹結(jié)構(gòu)容器

    基于Qt實現(xiàn)的自定義樹結(jié)構(gòu)容器

    在Qt框架中,盡管其提供了許多強大的容器類,但缺少一個通用的、靈活的樹結(jié)構(gòu)容器,所以本文將設(shè)計并實現(xiàn)一個可復(fù)用的自定義樹結(jié)構(gòu)容器,需要的可以參考下
    2024-12-12
  • C語言 OutputDebugString與格式化輸出函數(shù)OutputDebugPrintf案例詳解

    C語言 OutputDebugString與格式化輸出函數(shù)OutputDebugPrintf案例詳解

    這篇文章主要介紹了C語言 OutputDebugString與格式化輸出函數(shù)OutputDebugPrintf案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 示例詳解C++中的各種鎖

    示例詳解C++中的各種鎖

    C++中常見的鎖包括互斥鎖、遞歸互斥鎖、讀寫鎖、定時互斥鎖、遞歸定時互斥鎖、自旋鎖和條件變量,互斥鎖用于防止多線程同時訪問共享資源,遞歸互斥鎖允許同一線程多次獲取鎖,讀寫鎖區(qū)分讀寫操作,提高并發(fā)性
    2024-11-11
  • C語言結(jié)構(gòu)體struct詳解

    C語言結(jié)構(gòu)體struct詳解

    C語言中,結(jié)構(gòu)體類型屬于一種構(gòu)造類型(其他的構(gòu)造類型還有:數(shù)組類型,聯(lián)合類型),下面這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體(struct)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 基于C++編寫一個鍵盤提示音程序

    基于C++編寫一個鍵盤提示音程序

    首先講一下思路,這次制作的小黑子相當(dāng)于鍵盤提示音,輸入J,N,T,M,會發(fā)出“雞你太美”的聲音,連續(xù)按下JNTM則會發(fā)出“你干嘛啊,哎呦”的聲音,感興趣的可以了解一下
    2023-03-03
  • 關(guān)于C++STL string類的介紹及模擬實現(xiàn)

    關(guān)于C++STL string類的介紹及模擬實現(xiàn)

    這篇文章主要介紹了關(guān)于C++STL string類的介紹及模擬實現(xiàn)的相關(guān)資料,需要的朋友可以參考下面具體的文章內(nèi)容
    2021-09-09
  • C++重載運算符的規(guī)則詳解

    C++重載運算符的規(guī)則詳解

    運算符重載函數(shù)可以是類的成員函數(shù),也可以是類的友元函數(shù),還可以是既非類的成員函數(shù)也不是友元函數(shù)的普通函數(shù)
    2013-10-10
  • C++非遞歸建立二叉樹實例

    C++非遞歸建立二叉樹實例

    這篇文章主要介紹了C++非遞歸建立二叉樹的方法,實例分析了二叉樹的原理與C++實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04

最新評論

波密县| 辽阳市| 郸城县| 阳朔县| 永昌县| 汤阴县| 女性| 阜新市| 宜宾县| 多伦县| 青岛市| 镇原县| 化德县| 柏乡县| 桐乡市| 双鸭山市| 东城区| 澳门| 霍山县| 彩票| 沈丘县| 资源县| 宝丰县| 彭泽县| 凯里市| 乐陵市| 成安县| 娄底市| 金平| 仁怀市| 丰都县| 商河县| 曲沃县| 宁德市| 隆子县| 通州区| 长治县| 永安市| 栖霞市| 澄城县| 潜山县|