Qt программирование охранной системы видеонаблюдения 47-основные настройки

Qt
Qt программирование охранной системы видеонаблюдения 47-основные настройки

Введение

В системе должно быть много параметров конфигурации, хранящихся в файле конфигурации.Файл конфигурации может быть ini-файлом, json-файлом или текстовым файлом в произвольном формате.Я рекомендую ini-файл, потому что это очень удобно для чтения и записи узлов., поддерживает китайский контент, могут храниться различные встроенные в Qt типы данных, даже включая QByteArray, например, файл макета может храниться непосредственно в конфигурационном файле, представляющем собой набор непонятных символов. вы решили сохранить его в файле json, который люди не могут прочитать напрямую.

С увеличением функций, параметров узла, соответствующих конфигурационным файлам, становится все больше, и то же самое верно и для системы мониторинга.Помню, что в первой версии было всего около десяти параметров (название, операция запуска, интерфейс стиль и т.д.) В этой части основных настроек имеется десять переключателей, поэтому в процессе непрерывной итерации параметры конфигурации непрерывно делятся на категории и группы для хранения параметров конфигурации, что удобно для управления и легко читается и понять код.В основном интерфейсе разные группы соответствуют разным QGroupBox, поле группы соответствует настройке каждого параметра, переключатель может быть обозначен кнопкой переключения, а другие могут быть текстовыми полями и выпадающими окнами .

Мне нравится читать и записывать параметры конфигурации в отдельный класс, и при этом преобразовывать значения параметров конфигурации в соответствующие глобальные переменные.Это очень круто использовать.Большую часть параметров нужно использовать в более чем в одном месте.Очень эффективно делать маппинг с глобальными переменными.Высокий,класс параметров конфигурации,параметры конфигурации всей системы хранятся в ini файле,кроссплатформенность,все параметры соответствуют переменной,при чтении параметры конфигурации, присвойте значение переменной, при записи запишите значение переменной в документ конфигурации. Для того, чтобы изменение параметров можно было применить сразу (очень немногие нуждаются в автоматическом перезапуске приложения, например смена режима работы), при изменении параметра специально отправляется соответствующий сигнал, а место получения сигнала можно изменяться автоматически.

Описание основных параметров

  1. Операция запуска: после включения она автоматически запускается при запуске системы и включена по умолчанию.
  2. Автоматический вход: после включения он будет автоматически входить в систему с информацией о последнем вошедшем в систему пользователе, и по умолчанию он отключен.
  3. Запомнить пароль: если этот параметр включен, информация о последнем вошедшем в систему пользователе будет автоматически заполняться в форме входа, и по умолчанию эта функция отключена.
  4. Китайское название: китайское название строки заголовка в верхнем левом углу программного обеспечения, изменения будут применены немедленно.
  5. Английское название: английское название строки заголовка в верхнем левом углу программного обеспечения, изменения будут применены немедленно.
  6. Авторское право: Компания, которая владеет текущим авторским правом на программное обеспечение, где оно в настоящее время не отображается, запасное.
  7. Полноэкранный режим: если этот параметр включен, развернутый дисплей автоматически отображается в полноэкранном режиме вместо развернутого. По умолчанию он отключен.
  8. Полноэкранная адаптация: после включения автоматически использует метод перемещения на один пиксель вверх для устранения ошибки opengl.
  9. Значок программного обеспечения: автоматически считывается из папки с логотипом, вы можете выбрать соответствующий файл логотипа самостоятельно.
  10. Стиль интерфейса: Система поставляется с 17 наборами скинов, которые можно автоматически менять здесь, а видео по умолчанию черное.
  11. Режим работы: видеонаблюдение по умолчанию, дополнительное наблюдение за роботом, наблюдение с помощью дрона и т. д.
  12. Стиль навигации: используется для выбора стиля верхней панели навигации и левой панели навигации, верхняя сторона + левая сторона означает стиль верхней стороны верхней панели навигации (значок вверху, текст внизу), стиль слева левой панели навигации (иконка слева, текст справа).
  13. Время всплывающего окна: всплывающее сообщение в правом нижнем углу автоматически закрывает время. 0 секунд означает, что оно не будет закрыто навсегда.
  14. Звук будильника: 0 означает, что не включено, остальные означают количество звуков, воспроизводимых после будильника.
  15. Скрытие мыши: основной интерфейс автоматически скроет указатель мыши, если мышь не использовалась в течение длительного времени.Как правило, это необходимо установить во время полноэкранного опроса, и эффект будет лучше.
  16. Автоматический полноэкранный режим: мышь долгое время не работала в автоматическом полноэкранном режиме, 0 означает, что режим не включен.
  17. Запасной переключатель: зарезервирован для последующего использования.
  18. Picture alarm: номер сообщения графического полицейского модуля, 0 означает, что автоматический расчет выполнен, и полоса прокрутки не создается.
  19. Сообщение окна: номер строки сообщения модуля сообщений окна, 0 указывает, что автоматический расчет заполнен, и полоса прокрутки не создается.
  20. Значение прозрачности: значение прозрачности закрепленной формы, которое можно регулировать и применять динамически.

2. Особенности

(1) Программный модуль

  1. Модуль видеомониторинга, различные подмодули стыковки небольших окон, включая список устройств, графическую сигнализацию, информацию об окне, управление PTZ, предустановленное положение, настройку круиза, управление устройством, плавающую карту, просмотр веб-страниц и т. д.
  2. Модуль воспроизведения видео, включая локальное воспроизведение, удаленное воспроизведение, воспроизведение на устройстве, воспроизведение изображений, загрузку видео и т. д.
  3. Модуль электронной карты, включая карту изображений, онлайн-карту, автономную карту, планирование маршрута и т. д.
  4. Модуль запроса журнала, включая локальные журналы, журналы устройств и т. д.
  5. Модуль системных настроек, включая системные настройки (основные настройки, параметры видео, настройки базы данных, конфигурация карты, конфигурация последовательного порта и т. д.), управление регистратором, управление камерой, конфигурация опроса, управление пользователями и т. д.

(2) Основные функции

  1. Поддерживает различные видеопотоки (rtsp, rtmp, http и т. д.), видеофайлы (mp4, rmvb, avi и т. д.), воспроизведение с локальной USB-камеры.
  2. Поддержка многоэкранного переключения, включая переключение между 1, 4, 6, 8, 9, 13, 16, 25, 36, 64 экранами.
  3. Поддержка полноэкранного переключения, различные методы переключения включают контекстное меню мыши, кнопки панели инструментов, сочетания клавиш (alt+enter в полноэкранный режим, esc для выхода из полноэкранного режима).
  4. Поддерживает видеоопрос, включая опрос с 1, 4, 9 и 16 изображениями, и может устанавливать группу опроса (план опроса), интервал опроса, тип потока и т. д.
  5. Поддержка протокола onvif, включая поиск устройств, управление PTZ, управление устройствами (параметры изображения, время проверки, перезагрузка системы, моментальные снимки и т. д.).
  6. Поддержка управления разрешениями, разные пользователи могут соответствовать разным разрешениям модуля, таким как удаление журналов, завершение работы системы и т. д.
  7. База данных поддерживает различные базы данных, включая sqlite, mysql, sqlserver, postgresql, oracle, NPC Jincang и т. д.
  8. Локальная USB-камера поддерживает установку таких параметров, как разрешение и частота кадров.
  9. Все модули стыковки автоматически генерируют соответствующие меню для управления отображением и скрытием, которые можно открыть, щелкнув правой кнопкой мыши строку заголовка.
  10. Поддержка отображения всех модулей, скрытия всех модулей, сброса обычного макета, сброса полноэкранного макета.
  11. Дважды щелкните устройство, чтобы отобразить видео для предварительного просмотра в реальном времени, поддержку графических карт, онлайн-карт, автономных карт и т. д.
  12. Перетащите узел камеры в соответствующее окно, чтобы воспроизвести видео, и поддержите перетаскивание локальных файлов для прямого воспроизведения.
  13. Удаление видео поддерживается несколькими способами, такими как щелчок правой кнопкой мыши, закрытие полосы приостановки для удаления и перетаскивание видео за пределы панели видеонаблюдения для удаления.
  14. Кнопку устройства на карте изображения можно свободно перетаскивать, и информация о местоположении автоматически сохраняется. На карте Baidu вы можете щелкнуть мышью, чтобы получить информацию о широте и долготе, которая используется для обновления местоположения устройства.
  15. Любой канал в окне панели видеонаблюдения поддерживает перетаскивание и мгновенный отклик.
  16. Он включает в себя карту Baidu, переключение видов, отслеживание движения, точку устройства, нажатие мыши для получения широты и долготы и т. д.
  17. Двойной щелчок по узлу, перетаскивание узла, перетаскивание окна для обмена позициями и т. д. автоматически обновит и сохранит последний адрес воспроизведения, и программа автоматически применит его в следующий раз.
  18. Полоса громкости в правом нижнем углу автоматически скрывается, когда фокус теряется, а на полосе громкости есть значок отключения звука.
  19. Поддерживает скриншоты видео, вы можете указать один или все каналы для создания скриншотов, а также есть кнопка скриншота на небольшой панели инструментов внизу.
  20. Поддерживает автоматическое скрытие указателя мыши с течением времени, автоматический полноэкранный механизм.
  21. Поддержка onvif управления PTZ, может перемещать PTZ-камеру вверх, вниз, влево и вправо, включая сброс и регулировку фокуса.
  22. Поддержка любой камеры onvif, включая, помимо прочего, Hikvision, Dahua, Uniview, Tiandiweiye, Huawei и т. д.
  23. Видео может быть сохранено, дополнительное хранение времени или хранение одного файла, дополнительный интервал хранения.
  24. Вы можете установить режим передачи видеопотока tcp+udp, и вы можете установить декодирование видео на приоритет скорости, приоритет качества, выравнивание и т. д.
  25. Можно установить китайское название, английское название, значок LOGO и т. д. программного обеспечения.
  26. Сохраненные видеофайлы можно экспортировать в указанный каталог и загружать на сервер партиями.

(3) Особенности

  1. Основной интерфейс принимает режим формы стыковки, различные компоненты добавляются в виде небольших модулей, и любой модуль можно добавить, настроив его.
  2. Стыковочный модуль можно встроить и подвесить в любом месте путем перетаскивания, он поддерживает развертывание на весь экран и поддержку нескольких экранов.
  3. Механизм хранения файлов с двойной компоновкой, нормальный режим и полноэкранный режим соответствуют разным схемам компоновки, автоматически переключаются и сохраняются.Например, полноэкранный режим может выделять несколько модулей и отображать их прозрачно в назначенных позициях, что является более современным и научная фантастика.
  4. Оригинальный механизм протокола onvif, использующий базовый анализ протокола (поиск широковещательной рассылки udp + команда выполнения http-запроса), легче, проще для понимания, прост в освоении и расширении и не зависит от каких-либо сторонних компонентов, таких как gsoap.
  5. Исходный механизм импорта и экспорта данных, который не зависит от каких-либо компонентов на разных платформах, может экспортировать данные мгновенно.
  6. Благодаря встроенному множеству оригинальных компонентов вселенная очень ценна, включая компоненты импорта и экспорта данных (экспорт в xls, pdf, печать), компоненты базы данных (поток управления базой данных, поток автоматической очистки данных, универсальный пейджинг, запрос данных и т. д.) , компонент карты , компоненты видеонаблюдения, компоненты файлового многопоточного трансивера, компоненты связи onvif, общие компоненты ядра браузера и т. д.
  7. Пользовательское информационное окно + окно ошибки + окно запроса + окно подсказки в правом нижнем углу (включая несколько форматов) и т. д.
  8. Изысканная замена скинов, до 17 наборов стилей скинов можно заменить по желанию, все стили унифицированы, включая меню и т.д.
  9. Панель приостановки управления видео может добавлять несколько кнопок сама по себе, а небольшая панель инструментов в нижней части интерфейса мониторинга также может добавлять кнопки сама по себе.
  10. Дважды щелкните узел камеры, чтобы автоматически воспроизвести видео, дважды щелкните узел, чтобы автоматически добавить видео по порядку и автоматически перейти к следующему, и дважды щелкните родительский узел, чтобы автоматически добавить все видео под узлом. Основной поток и дополнительный поток являются необязательными.
  11. Управление рекордером, управление камерой, можно добавлять, удалять, изменять, импортировать и экспортировать информацию о печати, а также немедленно применять новую информацию об устройстве для создания древовидного списка без перезапуска.
  12. Различные ядра можно свободно переключать, ffmpeg, vlc, mpv и т. д. можно установить в pro. Рекомендуется использовать ffmpeg, который является наиболее кроссплатформенным, по умолчанию предоставляются скомпилированные библиотеки для linux и mac платформ.
  13. Поддержка жесткого декодирования, вы можете установить тип жесткого декодирования (qsv, dxva2, d3d11va и т. д.).
  14. По умолчанию для отрисовки видео используется opengl, который имеет сверхнизкое потребление ресурсов ЦП и поддерживает для отрисовки форматы yuyv и nv12, что очень мощно.
  15. Обладая широкими возможностями настройки, пользователи могут легко создавать на этой основе свои собственные функции, такие как добавление пользовательских модулей, добавление режимов работы, мониторинг роботов, мониторинг дронов, мониторинг экскаваторов и т. д.
  16. Поддержка xp, win7, win10, linux, mac, различных отечественных систем (UOS, win kylin, galaxy kylin и т. д.), встроенных linux и других систем.
  17. Полные комментарии, четкая структура проекта, очень подробное и полное руководство по использованию и разработке, точное функциональное описание каждого файла кода и непрерывные итерационные версии.

3. Адрес опыта

  1. Адрес опыта:disk.baidu.com/is/1's 7TH_GE Y…Код извлечения: 01jf Имя файла: bin_video_system.zip.
  2. Внутренний сайт:git ee.com/летающий свет…
  3. Международный сайт:GitHub.com/Летающий свет…
  4. Домашняя страница:blog.CSDN.net/Летающий свет…
  5. Знать домашнюю страницу:уууууу. call.com/people/fee…
  6. Онлайн-документация:Демонстрация виджета Feiyangqingyun.git ee.IO/Q…

В-четвертых, карта эффектов

在这里插入图片描述

Пять, основной код

void frmConfigSystem::initAppConfig1()
{
    QStringList styleNames, styleFiles;
    QUIStyle::getStyle(styleNames, styleFiles);
    for (int i = 0; i < styleNames.count(); i++) {
        ui->cboxStyleName->addItem(styleNames.at(i), styleFiles.at(i));
    }

    ui->cboxStyleName->setCurrentIndex(ui->cboxStyleName->findData(AppConfig::StyleName));
    connect(ui->cboxStyleName, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig1()));

    ui->txtCopyright->setText(AppConfig::Copyright);
    connect(ui->txtCopyright, SIGNAL(textChanged(QString)), this, SLOT(saveAppConfig1()));

    ui->txtTitleCn->setText(AppConfig::TitleCn);
    connect(ui->txtTitleCn, SIGNAL(textChanged(QString)), this, SLOT(saveAppConfig1()));

    ui->txtTitleEn->setText(AppConfig::TitleEn);
    connect(ui->txtTitleEn, SIGNAL(textChanged(QString)), this, SLOT(saveAppConfig1()));

    //设置移到 最左侧不然文字长了默认会在右边
    ui->txtCopyright->setCursorPosition(0);
    ui->txtTitleCn->setCursorPosition(0);
    ui->txtTitleEn->setCursorPosition(0);

    //从logo目录下加载所有图片
    QDir dir(QUIHelper::appPath() + "/logo");
    QStringList fileNames = dir.entryList(QStringList() << "*.png");
    foreach (QString fileName, fileNames) {
        ui->cboxLogoImage->addItem(fileName.split(".").first());
    }
    //如果一个都没有则添加一个空的防止配置文件被重置
    if (fileNames.count() == 0) {
        ui->cboxLogoImage->addItem(AppConfig::LogoImage);
    }

    ui->cboxLogoImage->setCurrentIndex(ui->cboxLogoImage->findText(AppConfig::LogoImage));
    connect(ui->cboxLogoImage, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig1()));
}

void frmConfigSystem::saveAppConfig1()
{
    int styleIndex = ui->cboxStyleName->currentIndex();
    QString styleName = ui->cboxStyleName->itemData(styleIndex).toString();
    if (AppConfig::StyleName != styleName) {
        AppConfig::StyleName = styleName;
        AppStyle::initStyle();
        AppEvent::Instance()->slot_changeStyle();
    }

    QString company = ui->txtCopyright->text().trimmed();
    if (AppConfig::Copyright != company) {
        AppConfig::Copyright = company;
        AppEvent::Instance()->slot_changeTitleInfo();
    }

    QString titleCn = ui->txtTitleCn->text().trimmed();
    if (AppConfig::TitleCn != titleCn) {
        AppConfig::TitleCn = titleCn;
        AppEvent::Instance()->slot_changeTitleInfo();
    }

    QString titleEn = ui->txtTitleEn->text().trimmed();
    if (AppConfig::TitleEn != titleEn) {
        AppConfig::TitleEn = titleEn;
        AppEvent::Instance()->slot_changeTitleInfo();
    }

    QString logoImage = ui->cboxLogoImage->currentText().trimmed();
    if (AppConfig::LogoImage != logoImage) {
        AppConfig::LogoImage = logoImage;
        AppEvent::Instance()->slot_changeLogo();
    }

    AppConfig::writeConfig();
}

void frmConfigSystem::initAppConfig2()
{
    QStringList listWorkMode;
    listWorkMode << "视频监控" << "机器人监控" << "无人机监控";
    ui->cboxWorkMode->addItems(listWorkMode);
    ui->cboxWorkMode->setCurrentIndex(AppConfig::WorkMode);
    connect(ui->cboxWorkMode, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));
    //ui->cboxWorkMode->setEnabled(AppConfig::WorkMode != 1);

    QStringList listNavStyle;
    listNavStyle << "左侧+左侧" << "左侧+上侧" << "上侧+左侧" << "上侧+上侧";
    ui->cboxNavStyle->addItems(listNavStyle);
    ui->cboxNavStyle->setCurrentIndex(AppConfig::NavStyle);
    connect(ui->cboxNavStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    QStringList listTime;
    listTime << "0秒钟" << "10秒钟" << "20秒钟" << "30秒钟" << "60秒钟" << "120秒钟";

    ui->cboxTimeHideCursor->addItems(listTime);
    QString timeHideCursor = QString("%1秒钟").arg(AppConfig::TimeHideCursor);
    ui->cboxTimeHideCursor->setCurrentIndex(ui->cboxTimeHideCursor->findText(timeHideCursor));
    connect(ui->cboxTimeHideCursor, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    ui->cboxTimeAutoFull->addItems(listTime);
    QString timeAutoFull = QString("%1秒钟").arg(AppConfig::TimeAutoFull);
    ui->cboxTimeAutoFull->setCurrentIndex(ui->cboxTimeAutoFull->findText(timeAutoFull));
    connect(ui->cboxTimeAutoFull, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    QStringList listCount;
    listCount << "0次" << "1次" << "3次" << "5次" << "10次" << "20次" << "50次" << "100次";

    ui->cboxAlarmSoundCount->addItems(listCount);
    QString alarmSoundCount = QString("%1次").arg(AppConfig::AlarmSoundCount);
    ui->cboxAlarmSoundCount->setCurrentIndex(ui->cboxAlarmSoundCount->findText(alarmSoundCount));
    connect(ui->cboxAlarmSoundCount, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    QStringList msgCount;
    msgCount << "0行" << "1行" << "3行" << "5行" << "10行" << "15行" << "20行" << "25行" << "30行" << "50行";

    ui->cboxMsgListCount->addItems(msgCount);
    QString msgListCount = QString("%1行").arg(AppConfig::MsgListCount);
    ui->cboxMsgListCount->setCurrentIndex(ui->cboxMsgListCount->findText(msgListCount));
    connect(ui->cboxMsgListCount, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    ui->cboxMsgTableCount->addItems(msgCount);
    QString msgTableCount = QString("%1行").arg(AppConfig::MsgTableCount);
    ui->cboxMsgTableCount->setCurrentIndex(ui->cboxMsgTableCount->findText(msgTableCount));
    connect(ui->cboxMsgTableCount, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));

    ui->labWindowOpacityValue->setText(QString::number(AppConfig::WindowOpacity));
    ui->sliderWindowOpacity->setValue(AppConfig::WindowOpacity);
    ui->sliderWindowOpacity->setRange(10, 100);
    connect(ui->sliderWindowOpacity, SIGNAL(valueChanged(int)), this, SLOT(saveAppConfig2()));

    QStringList listTipInterval;
    listTipInterval << "0秒钟" << "3秒钟" << "5秒钟" << "10秒钟" << "20秒钟" << "30秒钟" << "60秒钟" << "120秒" << "10000秒钟";
    ui->cboxTipInterval->addItems(listTipInterval);
    QString tipInterval = QString("%1秒钟").arg(AppConfig::TipInterval);
    ui->cboxTipInterval->setCurrentIndex(ui->cboxTipInterval->findText(tipInterval));
    connect(ui->cboxTipInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAppConfig2()));
}

void frmConfigSystem::saveAppConfig2()
{
    int workMode = ui->cboxWorkMode->currentIndex();
    if (AppConfig::WorkMode != workMode) {
        //先要发个退出信号出去通知我要准备退出啦
        AppEvent::Instance()->slot_exitAll();
        AppConfig::WorkMode = workMode;
        AppConfig::writeConfig();
        AppFun::reboot();
    }

    int navStyle = ui->cboxNavStyle->currentIndex();
    if (AppConfig::NavStyle != navStyle) {
        //先要发个退出信号出去通知我要准备退出啦
        AppEvent::Instance()->slot_exitAll();
        AppConfig::NavStyle = navStyle;
        AppConfig::writeConfig();
        AppFun::reboot();
    }

    QString timeHideCursor = ui->cboxTimeHideCursor->currentText();
    AppConfig::TimeHideCursor = timeHideCursor.mid(0, timeHideCursor.length() - 2).toInt();

    QString timeAutoFull = ui->cboxTimeAutoFull->currentText();
    AppConfig::TimeAutoFull = timeAutoFull.mid(0, timeAutoFull.length() - 2).toInt();

    QString alarmSoundCount = ui->cboxAlarmSoundCount->currentText();
    AppConfig::AlarmSoundCount = alarmSoundCount.mid(0, alarmSoundCount.length() - 1).toInt();

    QString msgListCount = ui->cboxMsgListCount->currentText();
    AppConfig::MsgListCount = msgListCount.mid(0, msgListCount.length() - 1).toInt();

    QString msgTableCount = ui->cboxMsgTableCount->currentText();
    AppConfig::MsgTableCount = msgTableCount.mid(0, msgTableCount.length() - 1).toInt();

    int windowOpacity = ui->sliderWindowOpacity->value();
    if (AppConfig::WindowOpacity != windowOpacity) {
        AppConfig::WindowOpacity = windowOpacity;
        ui->labWindowOpacityValue->setText(QString::number(AppConfig::WindowOpacity));
        AppEvent::Instance()->slot_changeWindowOpacity();
    }

    QString tipInterval = ui->cboxTipInterval->currentText();
    AppConfig::TipInterval = tipInterval.mid(0, tipInterval.length() - 2).toInt();

    AppConfig::writeConfig();
}