Qt開源作品42-視頻監控布局


一、前言

自從做監控系統以來,就一直有打算將這個功能獨立出來一個類,這樣的話很多系統用到此類布局切換,通用這個類就行,而且后期此布局會增加其他異形布局,甚至按照16:9之類的比例生成布局,之前此功能直接寫在功能界面UI類中,不方便拓展,好多個系統用到此功能,一旦增加了64布局、128通道布局等,都需要做對應更改,煩不勝煩,所以務必將此功能徹底剝離出來,為后面的256通道、異形布局、自定義布局打基礎。

通道切換在視頻監控系統中是最基礎的必備功能,一般都會提供1通道、4通道、6通道、8通道、9通道、16通道這幾個通道切換,可能做得比較好的還會提供24通道、32通道、64通道的,這個可能對電腦的配置就有一定要求了,一般來說,超過9個通道實時顯示視頻流,基本上會采用子碼流來顯示,如果都采用主碼流,電腦壓力非常巨大,CPU占用很高,內存也高,不過現在的電腦配置越來越高,基本上四千多塊錢的台式機,配置已經非常好了,顯示個16個通道的實時視頻毫無壓力。

Qt中的布局非常好用,尤其是QGridLayout表格布局,可以指定行列放置控件,而且還可以設置每個控件占用幾行幾列,這樣就可以完美的實現各種通道布局了。比如6通道,可以設置通道1占用兩行兩列,其他通道各站一行一列即可,當切換布局的時候,其他隱藏即可。

二、主要功能

  1. 將所有通道切換處理全部集中到一個類。
  2. 通用整數倍數布局切換函數,可方便拓展到100、255通道等。
  3. 通用異形布局切換函數,可以參考進行自定義異形布局。
  4. 通道布局切換發出信號通知。
  5. 可控每種布局切換菜單是否啟用。
  6. 支持自定義子菜單布局內容。
  7. 支持設置對應的菜單標識比如默認的通道字樣改成設備。

三、效果圖

四、開源主頁

  • 以上作品完整源碼下載都在開源主頁,會持續不斷更新作品數量和質量,歡迎各位關注。
  • 本開源項目已經成功升級到V2.0版本,分門別類,圖文並茂,保你爽到爆。
  • Qt開源武林秘籍開發經驗,看完學完,20K起薪,沒有找我!
  1. 國內站點:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 國際站點:https://github.com/feiyangqingyun/QWidgetDemo
  3. 開源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
  4. 個人主頁:https://qtchina.blog.csdn.net/
  5. 知乎主頁:https://www.zhihu.com/people/feiyangqingyun/

五、核心代碼

void VideoBox::change_video_normal(int index, int flag)
{
    //首先隱藏所有通道
    hide_video_all();
    int count = 0;
    int row = 0;
    int column = 0;

    //行列數一致的比如 2*2 3*4 4*4 5*5 等可以直接套用通用的公式
    //按照這個函數還可以非常容易的拓展出 10*10 16*16=256 通道界面
    for (int i = 0; i < videoCount; i++) {
        if (i >= index) {
            //添加到對應布局並設置可見
            gridLayout->addWidget(widgets.at(i), row, column);
            widgets.at(i)->setVisible(true);

            count++;
            column++;
            if (column == flag) {
                row++;
                column = 0;
            }
        }

        if (count == (flag * flag)) {
            break;
        }
    }
}

void VideoBox::change_video_custom(int index, int type)
{
    //從開始索引開始往后衍生多少個通道
    QList<int> indexs;
    for (int i = index; i < (index + type); ++i) {
        indexs << i;
    }

    if (type == 6) {
        change_video_6(indexs);
    } else if (type == 8) {
        change_video_8(indexs);
    } else if (type == 13) {
        change_video_13(indexs);
    }
}

void VideoBox::change_video_6(const QList<int> &indexs)
{
    //過濾防止索引越界
    if (indexs.count() < 6) {
        return;
    }

    //首先隱藏所有通道
    hide_video_all();
    //挨個重新添加到布局
    gridLayout->addWidget(widgets.at(indexs.at(0)), 0, 0, 2, 2);
    gridLayout->addWidget(widgets.at(indexs.at(1)), 0, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(2)), 1, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(3)), 2, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(4)), 2, 1, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(5)), 2, 0, 1, 1);
    //設置通道控件可見
    for (int i = indexs.first(); i <= indexs.last(); i++) {
        widgets.at(i)->setVisible(true);
    }
}

void VideoBox::change_video_8(const QList<int> &indexs)
{
    //過濾防止索引越界
    if (indexs.count() < 8) {
        return;
    }

    //首先隱藏所有通道
    hide_video_all();
    //挨個重新添加到布局
    gridLayout->addWidget(widgets.at(indexs.at(0)), 0, 0, 3, 3);
    gridLayout->addWidget(widgets.at(indexs.at(1)), 0, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(2)), 1, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(3)), 2, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(4)), 3, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(5)), 3, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(6)), 3, 1, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(7)), 3, 0, 1, 1);
    //設置通道控件可見
    for (int i = indexs.first(); i <= indexs.last(); i++) {
        widgets.at(i)->setVisible(true);
    }
}

void VideoBox::change_video_13(const QList<int> &indexs)
{
    //過濾防止索引越界
    if (indexs.count() < 13) {
        return;
    }

    //首先隱藏所有通道
    hide_video_all();
    //挨個重新添加到布局
    gridLayout->addWidget(widgets.at(indexs.at(0)), 0, 0, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(1)), 0, 1, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(2)), 0, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(3)), 0, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(4)), 1, 0, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(5)), 2, 0, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(6)), 1, 1, 2, 2);
    gridLayout->addWidget(widgets.at(indexs.at(7)), 1, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(8)), 2, 3, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(9)), 3, 0, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(10)), 3, 1, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(11)), 3, 2, 1, 1);
    gridLayout->addWidget(widgets.at(indexs.at(12)), 3, 3, 1, 1);
    //設置通道控件可見
    for (int i = indexs.first(); i <= indexs.last(); i++) {
        widgets.at(i)->setVisible(true);
    }
}

void VideoBox::change_video_1(int index)
{
    //首先隱藏所有通道
    hide_video_all();
    //添加通道到布局
    gridLayout->addWidget(widgets.at(index), 0, 0);
    //設置可見
    widgets.at(index)->setVisible(true);
}

void VideoBox::change_video_4(int index)
{
    change_video_normal(index, 2);
}

void VideoBox::change_video_6(int index)
{
    change_video_custom(index, 6);
}

void VideoBox::change_video_8(int index)
{
    change_video_custom(index, 8);
}

void VideoBox::change_video_9(int index)
{
    change_video_normal(index, 3);
}

void VideoBox::change_video_13(int index)
{
    change_video_custom(index, 13);
}

void VideoBox::change_video_16(int index)
{
    change_video_normal(index, 4);
}

void VideoBox::change_video_25(int index)
{
    change_video_normal(index, 5);
}

void VideoBox::change_video_36(int index)
{
    change_video_normal(index, 6);
}

void VideoBox::change_video_64(int index)
{
    change_video_normal(index, 8);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM