Qt編寫安防視頻監控系統20-錄像機管理

1、前言

錄像機管理模塊,在本系統中除了用來存儲NVR信息之外,方便生成對應的攝像機樹狀列表,目前沒有其餘用處,一個考慮是爲了方便後期拓展,好比改爲SDK內核加載視頻流和回放視頻等,甚至還須要作一些人臉識別之類的處理,這個就須要提供原始的NVR信息了,錄像機信息主要包括名稱、類型(廠家,後期用來決定區分採用何種協議)、IP地址、用戶姓名、用戶密碼、啓用狀態、安裝位置,其中用戶信息用來登陸NVR驗證,安裝位置用來統計或者生成設備分佈圖,或者上傳到第三方的大平臺須要上報經緯度安裝位置等信息。linux

通常這種小數據量的表格,比較固定,並且數據量也很少,一般直接加載數據庫表來顯示,使用的是QSqlTableModel類,該類繼承QSqlQueryModel,只須要設置一個表名便可加載,使用仍是很是方便的,這裏須要提的就是自定義委託,當設置好表格能夠直接修改數據提交之後寫入到數據庫,多多少少該表中就須要用到自定義委託,好比提供下拉框選擇數據、密碼文本框、提供日期框選擇日期時間、提供微調框設置整數浮點數等,爲此特地封裝了一個超級自定義委託類,該類每次使用只須要new便可,無需給每一個表格控件都繼承或者設置不同的委託,該組件徹底開源。c++

分頁組件開源地址:https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo 文件名稱:dbpagegit

體驗地址:https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe 文件名稱:bin_video_system.zipgithub

2、功能特色

  1. 支持16畫面切換,全屏切換等,包括1+4+6+8+9+13+16畫面切換。
  2. 支持alt+enter全屏,esc退出全屏。
  3. 自定義信息框+錯誤框+詢問框+右下角提示框。
  4. 17套皮膚樣式隨意更換,全部樣式所有統一,包括菜單等。
  5. 雲臺儀表盤鼠標移上去高亮,八個方位精準識別。
  6. 底部畫面工具欄(畫面分割切換+截圖聲音等設置)移上去高亮。
  7. 可在配置文件更改左上角logo+中文軟件名稱+英文軟件名稱。
  8. 封裝了百度地圖,三維切換,設備點位,鼠標按下獲取經緯度等。
  9. 堆棧窗體,每一個窗體都是個單獨的qwidget,方便編寫本身的代碼。
  10. 頂部鼠標右鍵菜單,可動態控制時間CPU+左上角面板+左下角面板+右上角面板+右下角面板的顯示和隱藏,支持恢復默認佈局。
  11. 工具欄能夠放置多個小圖標和關閉圖標。
  12. 左側右側可拖動拉伸,並自動記憶寬高位置,重啓後恢復。
  13. 雙擊攝像機節點自動播放視頻,雙擊節點自動依次添加視頻,會自動跳到下一個,雙擊父節點自動添加該節點下的全部視頻。
  14. 攝像機節點拖曳到對應窗體播放視頻,同時支持拖曳本地文件直接播放。
  15. 視頻畫面窗體支持拖曳交換,瞬間響應。
  16. 雙擊節點+拖曳節點+拖曳窗體交換位置,均自動更新url.txt。
  17. 支持從url.txt中加載16通道視頻播放,自動記憶最後通道對應的視頻,軟件啓動後自動打開播放。
  18. 右下角音量條控件,失去焦點自動隱藏,音量條帶靜音圖標。
  19. 集成百度地圖,能夠添加設備對應位置,自動生成地圖,支持縮放和三維地圖,提供地圖風格選擇,共12種風格。
  20. 視頻拖動到通道窗體外自動刪除視頻。
  21. 鼠標右鍵可刪除當前+全部視頻,截圖當前+全部視頻。
  22. 錄像機管理、攝像機管理,可添加刪除修改導入導出打印信息,當即應用新的設備信息生成樹狀列表,不需重啓。
  23. 在pro文件中能夠自由開啓是否加載地圖。
  24. 視頻播放可選四種內核自由切換,vlc+ffmpeg+easyplayer+海康sdk,都可在pro中設置。
  25. 可設置1+4+9+16畫面輪詢,可設置輪詢間隔以及輪詢碼流類型等,直接在主界面底部工具欄右側單擊啓動輪詢按鈕便可,再次單擊中止輪詢。
  26. 默認超過10秒鐘未操做自動隱藏鼠標指針。
  27. 支持onvif搜素設備,支持任意onvif攝像機,包括但不限於海康大華宇視天地偉業華爲等,支持onvif雲臺控制。
  28. 高度可定製化,用戶能夠很方便的在此基礎上衍生本身的功能,支持linux系統。

3、效果圖

4、核心代碼

#include "frmconfignvr.h"
#include "ui_frmconfignvr.h"
#include "quiwidget.h"
#include "dbhelper.h"
#include "dbdelegate.h"
#include "excelapi.h"
#include "printapi.h"
#include "api.h"

frmConfigNvr::frmConfigNvr(QWidget *parent) : QWidget(parent), ui(new Ui::frmConfigNvr)
{
    ui->setupUi(this);
    this->initForm();
    this->initData();
}

frmConfigNvr::~frmConfigNvr()
{
    delete ui;
}

void frmConfigNvr::initForm()
{
    ui->widgetTop->setProperty("flag", "navbtn");
    ui->labTip->setText("提示 → 必須和現場信息一致,改動後需重啓應用");
    API::initTableView(ui->tableView);
}

void frmConfigNvr::initData()
{
    model = new QSqlTableModel(this);
    model->setTable("NvrInfo");
    model->setSort(0, Qt::AscendingOrder);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();

    ui->tableView->setModel(model);
    ui->tableView->setProperty("model", true);

    columnNames.clear();
    columnNames << "編號" << "名稱" << "類型" << "IP地址" << "用戶姓名" << "用戶密碼" << "狀態" << "安裝位置";

    columnWidths.clear();
    columnWidths << 60 << 120 << 80 << 130 << 100 << 130 << 60 << 200;

    for (int i = 0; i < columnNames.count(); i++) {
        model->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
        ui->tableView->setColumnWidth(i, columnWidths.at(i));
    }

    //類型委託
    DbDelegate *d_cbox_nvrType = new DbDelegate(this);
    d_cbox_nvrType->setDelegateType("QComboBox");
    d_cbox_nvrType->setDelegateValue(DBData::NvrTypes);
    ui->tableView->setItemDelegateForColumn(2, d_cbox_nvrType);

    //用戶密碼委託
    DbDelegate *d_txt_userPwd = new DbDelegate(this);
    d_txt_userPwd->setDelegateType("QLineEdit");
    d_txt_userPwd->setDelegatePwd(true);
    d_txt_userPwd->setDelegateColumn(5);
    ui->tableView->setItemDelegateForColumn(5, d_txt_userPwd);

    //狀態委託
    QStringList nvrEnable;
    nvrEnable << "啓用" << "禁用";
    DbDelegate *d_cbox_nvrEnable = new DbDelegate(this);
    d_cbox_nvrEnable->setDelegateType("QComboBox");
    d_cbox_nvrEnable->setDelegateValue(nvrEnable);
    ui->tableView->setItemDelegateForColumn(6, d_cbox_nvrEnable);

    //用來切換樣式自動改變顏色
    delegates << d_cbox_nvrType;
    delegates << d_txt_userPwd;
    delegates << d_cbox_nvrEnable;
}

void frmConfigNvr::changeStyle()
{
    foreach (DbDelegate *delegate, delegates) {
        delegate->setTextColor(QUIConfig::TextColor);
        delegate->setSelectBgColor(QUIConfig::NormalColorStart);
    }
}

void frmConfigNvr::on_btnAdd_clicked()
{
    int count = model->rowCount();
    model->insertRow(count);

    int nvrID = model->index(count - 1, 0).data().toInt() + 1;
    QString nvrName = model->index(count - 1, 1).data().toString();
    QString nvrType = model->index(count - 1, 2).data().toString();
    QString nvrIP = model->index(count - 1, 3).data().toString();
    QString userName = model->index(count - 1, 4).data().toString();
    QString userPwd = model->index(count - 1, 5).data().toString();
    QString nvrEnable = model->index(count - 1, 6).data().toString();
    QString nvrAddr = model->index(count - 1, 7).data().toString();

    if (nvrName.startsWith("錄像機#")) {
        nvrName = QString("錄像機#%1").arg(nvrID);
    }

    if (count == 0) {
        nvrID = 1;
        nvrName = "錄像機#1";
        nvrType = "海康";
        nvrIP = "192.168.1.128";
        userName = "admin";
        userPwd = "admin";
        nvrEnable = "啓用";
        nvrAddr = "錄像機的安裝位置";
    }

    //設置新增長的行默認值
    model->setData(model->index(count, 0), nvrID);
    model->setData(model->index(count, 1), nvrName);
    model->setData(model->index(count, 2), nvrType);
    model->setData(model->index(count, 3), nvrIP);
    model->setData(model->index(count, 4), userName);
    model->setData(model->index(count, 5), userPwd);
    model->setData(model->index(count, 6), nvrEnable);
    model->setData(model->index(count, 7), nvrAddr);
    ui->tableView->setCurrentIndex(model->index(count, 0));
}

void frmConfigNvr::on_btnSave_clicked()
{
    model->database().transaction();
    if (model->submitAll()) {
        model->database().commit();
        DBHelper::loadNvrInfo();
        emit nvrNameChanged();
    } else {
        model->database().rollback();
        QUIHelper::showMessageBoxError("保存信息失敗,信息不能爲空,請從新填寫!");
    }
}

void frmConfigNvr::on_btnDelete_clicked()
{
    if (ui->tableView->currentIndex().row() < 0) {
        QUIHelper::showMessageBoxError("請選擇要刪除的錄像機!");
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("肯定要刪除該錄像機嗎? 錄像機對應的全部攝像機都會被刪除!") == QMessageBox::Yes) {
        int row = ui->tableView->currentIndex().row();
        QString nvrName = model->index(row, 1).data().toString();
        DBHelper::deleteIpcInfo(nvrName);

        model->removeRow(row);
        model->submitAll();
        ui->tableView->setCurrentIndex(model->index(model->rowCount() - 1, 0));
    }
}

void frmConfigNvr::on_btnReturn_clicked()
{
    model->revertAll();
}

void frmConfigNvr::on_btnClear_clicked()
{
    if (model->rowCount() <= 0) {
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("肯定要清空全部錄像機信息嗎?") == QMessageBox::Yes) {
        DBHelper::clearNvrInfo();
        model->select();
    }
}

void frmConfigNvr::on_btnExcel_clicked()
{
    QString name = "錄像機信息";
    QString fileName = QString("%1_%2").arg(name).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"));
    QString file = API::getSaveFileNames(fileName, "Excel(*.xls)");
    if (file.isEmpty()) {
        return;
    }

    QString columns = "*";
    QString where = "order by NvrID asc";
    QStringList content = DBHelper::getContent("NvrInfo", columns, where, "", ";");

    int rowCount = content.count();
    if (rowCount == 0) {
        QUIHelper::showMessageBoxError("沒有要處理的數據!");
        return;
    }

    QList<QString> columnNames = this->columnNames;
    QList<int> columnWidths = this->columnWidths;
    columnWidths[7] = 350;

    ExcelAPI::Instance()->saveExcel(file, name, name, "", columnNames, columnWidths, content);
    QString msg = QString("導出%1到Excel").arg(name);
    DBHelper::addUserLog("用戶操做", msg);

    if (QUIHelper::showMessageBoxQuestion(msg + "成功!肯定如今就打開嗎?") == QMessageBox::Yes) {
        QString url = QString("file:///%1").arg(file);
        QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
    }
}

void frmConfigNvr::on_btnPrint_clicked()
{
    QString name = "錄像機信息";
    QString columns = "*";
    QString where = "order by NvrID asc";
    QStringList content = DBHelper::getContent("NvrInfo", columns, where, "", ";");

    int rowCount = content.count();
    if (rowCount == 0) {
        QUIHelper::showMessageBoxError("沒有要處理的數據!");
        return;
    }

    QList<QString> columnNames = this->columnNames;
    QList<int> columnWidths = this->columnWidths;
    columnWidths[7] = 350;

    PrintAPI::Instance()->print(name, "", columnNames, columnWidths, content, true);
    QString msg = QString("打印%1").arg(name);
    DBHelper::addUserLog("用戶操做", msg);
}
相關文章
相關標籤/搜索