From c54fec1992fa08496c7ba19e4069ed97d7ea7920 Mon Sep 17 00:00:00 2001 From: feiyangqingyun Date: Mon, 17 May 2021 14:43:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0snap/{buttondefence.gif => devicebutton.gif} | Bin README.md | 4 +- buttondefence/buttondefence.h | 99 ------------------ buttondefence/frmbuttondefence.cpp | 71 ------------- buttondefence/frmbuttondefence.h | 36 ------- buttondefence/main.qrc | 35 ------- .../devicebutton.cpp | 64 +++++------ devicebutton/devicebutton.h | 99 ++++++++++++++++++ .../devicebutton.pro | 12 +-- devicebutton/frmdevicebutton.cpp | 71 +++++++++++++ devicebutton/frmdevicebutton.h | 36 +++++++ .../frmdevicebutton.ui | 24 ++--- .../image/bg_call.jpg | Bin .../devicebutton_black_bubble.png | Bin .../devicebutton_black_bubble2.png | Bin .../devicebutton_black_circle.png | Bin .../devicebutton/devicebutton_black_msg.png | Bin .../devicebutton/devicebutton_black_msg2.png | Bin .../devicebutton_black_police.png | Bin .../devicebutton/devicebutton_blue_bubble.png | Bin .../devicebutton_blue_bubble2.png | Bin .../devicebutton/devicebutton_blue_circle.png | Bin .../devicebutton/devicebutton_blue_msg.png | Bin .../devicebutton/devicebutton_blue_msg2.png | Bin .../devicebutton/devicebutton_blue_police.png | Bin .../devicebutton/devicebutton_gray_bubble.png | Bin .../devicebutton_gray_bubble2.png | Bin .../devicebutton/devicebutton_gray_circle.png | Bin .../devicebutton/devicebutton_gray_msg.png | Bin .../devicebutton/devicebutton_gray_msg2.png | Bin .../devicebutton/devicebutton_gray_police.png | Bin .../devicebutton_green_bubble.png | Bin .../devicebutton_green_bubble2.png | Bin .../devicebutton_green_circle.png | Bin .../devicebutton/devicebutton_green_msg.png | Bin .../devicebutton/devicebutton_green_msg2.png | Bin .../devicebutton_green_police.png | Bin .../devicebutton/devicebutton_red_bubble.png | Bin .../devicebutton/devicebutton_red_bubble2.png | Bin .../devicebutton/devicebutton_red_circle.png | Bin .../devicebutton/devicebutton_red_msg.png | Bin .../devicebutton/devicebutton_red_msg2.png | Bin .../devicebutton/devicebutton_red_police.png | Bin {buttondefence => devicebutton}/main.cpp | 6 +- devicebutton/main.qrc | 35 +++++++ web/video_system.html | 13 +-- 46 files changed, 303 insertions(+), 302 deletions(-) rename 0snap/{buttondefence.gif => devicebutton.gif} (100%) delete mode 100644 buttondefence/buttondefence.h delete mode 100644 buttondefence/frmbuttondefence.cpp delete mode 100644 buttondefence/frmbuttondefence.h delete mode 100644 buttondefence/main.qrc rename buttondefence/buttondefence.cpp => devicebutton/devicebutton.cpp (68%) create mode 100644 devicebutton/devicebutton.h rename buttondefence/buttondefence.pro => devicebutton/devicebutton.pro (63%) create mode 100644 devicebutton/frmdevicebutton.cpp create mode 100644 devicebutton/frmdevicebutton.h rename buttondefence/frmbuttondefence.ui => devicebutton/frmdevicebutton.ui (87%) rename {buttondefence => devicebutton}/image/bg_call.jpg (100%) rename buttondefence/image/buttondefence/btn_defence_error_bubble.png => devicebutton/image/devicebutton/devicebutton_black_bubble.png (100%) rename buttondefence/image/buttondefence/btn_defence_error_bubble2.png => devicebutton/image/devicebutton/devicebutton_black_bubble2.png (100%) rename buttondefence/image/buttondefence/btn_defence_error_circle.png => devicebutton/image/devicebutton/devicebutton_black_circle.png (100%) rename buttondefence/image/buttondefence/btn_defence_error_msg.png => devicebutton/image/devicebutton/devicebutton_black_msg.png (100%) rename buttondefence/image/buttondefence/btn_defence_error_msg2.png => devicebutton/image/devicebutton/devicebutton_black_msg2.png (100%) rename buttondefence/image/buttondefence/btn_defence_error_police.png => devicebutton/image/devicebutton/devicebutton_black_police.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_bubble.png => devicebutton/image/devicebutton/devicebutton_blue_bubble.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_bubble2.png => devicebutton/image/devicebutton/devicebutton_blue_bubble2.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_circle.png => devicebutton/image/devicebutton/devicebutton_blue_circle.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_msg.png => devicebutton/image/devicebutton/devicebutton_blue_msg.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_msg2.png => devicebutton/image/devicebutton/devicebutton_blue_msg2.png (100%) rename buttondefence/image/buttondefence/btn_defence_disarming_police.png => devicebutton/image/devicebutton/devicebutton_blue_police.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_bubble.png => devicebutton/image/devicebutton/devicebutton_gray_bubble.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_bubble2.png => devicebutton/image/devicebutton/devicebutton_gray_bubble2.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_circle.png => devicebutton/image/devicebutton/devicebutton_gray_circle.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_msg.png => devicebutton/image/devicebutton/devicebutton_gray_msg.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_msg2.png => devicebutton/image/devicebutton/devicebutton_gray_msg2.png (100%) rename buttondefence/image/buttondefence/btn_defence_bypass_police.png => devicebutton/image/devicebutton/devicebutton_gray_police.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_bubble.png => devicebutton/image/devicebutton/devicebutton_green_bubble.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_bubble2.png => devicebutton/image/devicebutton/devicebutton_green_bubble2.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_circle.png => devicebutton/image/devicebutton/devicebutton_green_circle.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_msg.png => devicebutton/image/devicebutton/devicebutton_green_msg.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_msg2.png => devicebutton/image/devicebutton/devicebutton_green_msg2.png (100%) rename buttondefence/image/buttondefence/btn_defence_arming_police.png => devicebutton/image/devicebutton/devicebutton_green_police.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_bubble.png => devicebutton/image/devicebutton/devicebutton_red_bubble.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_bubble2.png => devicebutton/image/devicebutton/devicebutton_red_bubble2.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_circle.png => devicebutton/image/devicebutton/devicebutton_red_circle.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_msg.png => devicebutton/image/devicebutton/devicebutton_red_msg.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_msg2.png => devicebutton/image/devicebutton/devicebutton_red_msg2.png (100%) rename buttondefence/image/buttondefence/btn_defence_alarm_police.png => devicebutton/image/devicebutton/devicebutton_red_police.png (100%) rename {buttondefence => devicebutton}/main.cpp (87%) create mode 100644 devicebutton/main.qrc diff --git a/0snap/buttondefence.gif b/0snap/devicebutton.gif similarity index 100% rename from 0snap/buttondefence.gif rename to 0snap/devicebutton.gif diff --git a/README.md b/README.md index e30d1ef..d44fc54 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ | 22 | lineeditnext | 文本框回车焦点下移 | | 23 | zhtopy | 汉字转拼音 | | 24 | qwtdemo | qwt的源码版本,无需插件,直接源码集成到你的项目即可 | -| 25 | buttondefence | 通用按钮地图效果 | +| 25 | devicebutton | 设备按钮地图效果 | | 26 | mouseline | 鼠标定位十字线 | | 27 | emailtool | 邮件发送工具 | | 28 | ntpclient | NTP服务器时间同步 | @@ -81,7 +81,7 @@ ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/lineeditnext.gif) ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/zhtopy.gif) ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/qwtdemo.jpg) -![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/buttondefence.gif) +![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/devicebutton.gif) ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/mouseline.gif) ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/emailtool.gif) ![avatar](https://gitee.com/feiyangqingyun/QWidgetDemo/raw/master/0snap/ntpclient.gif) diff --git a/buttondefence/buttondefence.h b/buttondefence/buttondefence.h deleted file mode 100644 index 8c300bc..0000000 --- a/buttondefence/buttondefence.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BUTTONDEFENCE_H -#define BUTTONDEFENCE_H - -/** - * 防区按钮控件 作者:feiyangqingyun(QQ:517216493) 2018-7-2 - * 1. 可设置防区样式 圆形、警察、气泡、气泡2、消息、消息2 - * 2. 可设置防区状态 布防、撤防、报警、旁路、故障 - * 3. 可设置报警切换 - * 4. 可设置显示的防区号 - * 5. 可设置是否可鼠标拖动 - * 6. 发出单击和双击信号 - */ - -#include - -#ifdef quc -class Q_DECL_EXPORT ButtonDefence : public QWidget -#else -class ButtonDefence : public QWidget -#endif - -{ - Q_OBJECT - Q_ENUMS(ButtonStyle) - Q_ENUMS(ButtonStatus) - - Q_PROPERTY(bool canMove READ getCanMove WRITE setCanMove) - Q_PROPERTY(QString text READ getText WRITE setText) - - Q_PROPERTY(ButtonStyle buttonStyle READ getButtonStyle WRITE setButtonStyle) - Q_PROPERTY(ButtonStatus buttonStatus READ getButtonStatus WRITE setButtonStatus) - -public: - //防区样式 圆形、警察、气泡、气泡2、消息、消息2 - enum ButtonStyle { - ButtonStyle_Circle = 0, - ButtonStyle_Police = 1, - ButtonStyle_Bubble = 2, - ButtonStyle_Bubble2 = 3, - ButtonStyle_Msg = 4, - ButtonStyle_Msg2 = 5 - }; - - //防区状态 布防、撤防、报警、旁路、故障 - enum ButtonStatus { - ButtonStatus_Arming = 0, - ButtonStatus_Disarming = 1, - ButtonStatus_Alarm = 2, - ButtonStatus_Bypass = 3, - ButtonStatus_Error = 4 - }; - - explicit ButtonDefence(QWidget *parent = 0); - ~ButtonDefence(); - -protected: - void paintEvent(QPaintEvent *); - bool eventFilter(QObject *watched, QEvent *event); - -private: - bool canMove; //是否可移动 - QString text; //显示文字 - ButtonStyle buttonStyle; //防区样式 - ButtonStatus buttonStatus; //防区状态 - - QString type; //图片末尾类型 - QString imgName; //背景图片名称 - bool isDark; //是否加深报警 - QTimer *timer; //报警闪烁定时器 - -private slots: - void checkAlarm(); - -public: - bool getCanMove() const; - QString getText() const; - - ButtonStyle getButtonStyle() const; - ButtonStatus getButtonStatus() const; - - QSize sizeHint() const; - QSize minimumSizeHint() const; - -public Q_SLOTS: - //设置可移动 - void setCanMove(bool canMove); - //设置显示文字 - void setText(const QString &text); - //设置防区样式 - void setButtonStyle(const ButtonStyle &buttonStyle); - //设置防区状态 - void setButtonStatus(const ButtonStatus &buttonStatus); - -Q_SIGNALS: - void clicked(); - void doubleClicked(); -}; - -#endif //BUTTONDEFENCE_H diff --git a/buttondefence/frmbuttondefence.cpp b/buttondefence/frmbuttondefence.cpp deleted file mode 100644 index 03cce01..0000000 --- a/buttondefence/frmbuttondefence.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "frmbuttondefence.h" -#include "ui_frmbuttondefence.h" -#include "buttondefence.h" -#include "qdebug.h" - -frmButtonDefence::frmButtonDefence(QWidget *parent) : QWidget(parent), ui(new Ui::frmButtonDefence) -{ - ui->setupUi(this); - this->initForm(); -} - -frmButtonDefence::~frmButtonDefence() -{ - delete ui; -} - -void frmButtonDefence::initForm() -{ - //设置背景地图 - ui->labMap->setStyleSheet("border-image:url(:/image/bg_call.jpg);"); - - btn1 = new ButtonDefence(ui->labMap); - btn1->setText("#1"); - btn1->setGeometry(5, 5, 35, 35); - - btn2 = new ButtonDefence(ui->labMap); - btn2->setText("#2"); - btn2->setGeometry(45, 5, 35, 35); - - btn3 = new ButtonDefence(ui->labMap); - btn3->setText("#3"); - btn3->setGeometry(85, 5, 35, 35); - - btnStyle << ui->btnCircle << ui->btnPolice << ui->btnBubble << ui->btnBubble2 << ui->btnMsg << ui->btnMsg2; - foreach (QPushButton *btn, btnStyle) { - connect(btn, SIGNAL(clicked(bool)), this, SLOT(changeStyle())); - } - - btnStatus << ui->btnArming << ui->btnDisarming << ui->btnAlarm << ui->btnBypass << ui->btnError; - foreach (QPushButton *btn, btnStatus) { - connect(btn, SIGNAL(clicked(bool)), this, SLOT(changeStatus())); - } -} - -void frmButtonDefence::changeStyle() -{ - QPushButton *btn = (QPushButton *)sender(); - int index = btnStyle.indexOf(btn); - ButtonDefence::ButtonStyle style = (ButtonDefence::ButtonStyle)index; - btn1->setButtonStyle(style); - btn2->setButtonStyle(style); - btn3->setButtonStyle(style); -} - -void frmButtonDefence::changeStatus() -{ - QPushButton *btn = (QPushButton *)sender(); - int index = btnStatus.indexOf(btn); - ButtonDefence::ButtonStatus style = (ButtonDefence::ButtonStatus)index; - btn1->setButtonStatus(style); - btn2->setButtonStatus(style); - btn3->setButtonStatus(style); -} - -void frmButtonDefence::on_ckCanMove_stateChanged(int arg1) -{ - bool canMove = (arg1 != 0); - btn1->setCanMove(canMove); - btn2->setCanMove(canMove); - btn3->setCanMove(canMove); -} diff --git a/buttondefence/frmbuttondefence.h b/buttondefence/frmbuttondefence.h deleted file mode 100644 index e815330..0000000 --- a/buttondefence/frmbuttondefence.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef FRMBUTTONDEFENCE_H -#define FRMBUTTONDEFENCE_H - -#include - -class ButtonDefence; -class QPushButton; - -namespace Ui { -class frmButtonDefence; -} - -class frmButtonDefence : public QWidget -{ - Q_OBJECT - -public: - explicit frmButtonDefence(QWidget *parent = 0); - ~frmButtonDefence(); - -private slots: - void initForm(); - void changeStyle(); - void changeStatus(); - void on_ckCanMove_stateChanged(int arg1); - -private: - Ui::frmButtonDefence *ui; - ButtonDefence *btn1; - ButtonDefence *btn2; - ButtonDefence *btn3; - QList btnStyle; - QList btnStatus; -}; - -#endif // FRMBUTTONDEFENCE_H diff --git a/buttondefence/main.qrc b/buttondefence/main.qrc deleted file mode 100644 index c0e3c1f..0000000 --- a/buttondefence/main.qrc +++ /dev/null @@ -1,35 +0,0 @@ - - - image/bg_call.jpg - image/buttondefence/btn_defence_alarm_bubble.png - image/buttondefence/btn_defence_alarm_bubble2.png - image/buttondefence/btn_defence_alarm_circle.png - image/buttondefence/btn_defence_alarm_msg.png - image/buttondefence/btn_defence_alarm_msg2.png - image/buttondefence/btn_defence_alarm_police.png - image/buttondefence/btn_defence_arming_bubble.png - image/buttondefence/btn_defence_arming_bubble2.png - image/buttondefence/btn_defence_arming_circle.png - image/buttondefence/btn_defence_arming_msg.png - image/buttondefence/btn_defence_arming_msg2.png - image/buttondefence/btn_defence_arming_police.png - image/buttondefence/btn_defence_bypass_bubble.png - image/buttondefence/btn_defence_bypass_bubble2.png - image/buttondefence/btn_defence_bypass_circle.png - image/buttondefence/btn_defence_bypass_msg.png - image/buttondefence/btn_defence_bypass_msg2.png - image/buttondefence/btn_defence_bypass_police.png - image/buttondefence/btn_defence_disarming_bubble.png - image/buttondefence/btn_defence_disarming_bubble2.png - image/buttondefence/btn_defence_disarming_circle.png - image/buttondefence/btn_defence_disarming_msg.png - image/buttondefence/btn_defence_disarming_msg2.png - image/buttondefence/btn_defence_disarming_police.png - image/buttondefence/btn_defence_error_bubble.png - image/buttondefence/btn_defence_error_bubble2.png - image/buttondefence/btn_defence_error_circle.png - image/buttondefence/btn_defence_error_msg.png - image/buttondefence/btn_defence_error_msg2.png - image/buttondefence/btn_defence_error_police.png - - diff --git a/buttondefence/buttondefence.cpp b/devicebutton/devicebutton.cpp similarity index 68% rename from buttondefence/buttondefence.cpp rename to devicebutton/devicebutton.cpp index c869f7d..5c250bb 100644 --- a/buttondefence/buttondefence.cpp +++ b/devicebutton/devicebutton.cpp @@ -1,20 +1,20 @@ #pragma execution_character_set("utf-8") -#include "buttondefence.h" +#include "devicebutton.h" #include "qpainter.h" #include "qevent.h" #include "qtimer.h" #include "qdebug.h" -ButtonDefence::ButtonDefence(QWidget *parent) : QWidget(parent) +DeviceButton::DeviceButton(QWidget *parent) : QWidget(parent) { canMove = false; text = "1"; buttonStyle = ButtonStyle_Police; - buttonStatus = ButtonStatus_Arming; + buttonColor = ButtonColor_Green; type = "police"; - imgName = QString(":/image/buttondefence/btn_defence_disarming_%1.png").arg(type); + imgName = QString(":/image/devicebutton/devicebutton_green_%1.png").arg(type); isDark = false; timer = new QTimer(this); @@ -24,14 +24,14 @@ ButtonDefence::ButtonDefence(QWidget *parent) : QWidget(parent) this->installEventFilter(this); } -ButtonDefence::~ButtonDefence() +DeviceButton::~DeviceButton() { if (timer->isActive()) { timer->stop(); } } -void ButtonDefence::paintEvent(QPaintEvent *) +void DeviceButton::paintEvent(QPaintEvent *) { double width = this->width(); double height = this->height(); @@ -77,7 +77,7 @@ void ButtonDefence::paintEvent(QPaintEvent *) painter.drawText(rect, Qt::AlignCenter, text); } -bool ButtonDefence::eventFilter(QObject *watched, QEvent *event) +bool DeviceButton::eventFilter(QObject *watched, QEvent *event) { if (canMove) { static QPoint lastPoint; @@ -109,54 +109,54 @@ bool ButtonDefence::eventFilter(QObject *watched, QEvent *event) return QWidget::eventFilter(watched, event); } -bool ButtonDefence::getCanMove() const +bool DeviceButton::getCanMove() const { return this->canMove; } -QString ButtonDefence::getText() const +QString DeviceButton::getText() const { return this->text; } -ButtonDefence::ButtonStyle ButtonDefence::getButtonStyle() const +DeviceButton::ButtonStyle DeviceButton::getButtonStyle() const { return this->buttonStyle; } -ButtonDefence::ButtonStatus ButtonDefence::getButtonStatus() const +DeviceButton::ButtonColor DeviceButton::getButtonColor() const { - return this->buttonStatus; + return this->buttonColor; } -QSize ButtonDefence::sizeHint() const +QSize DeviceButton::sizeHint() const { return QSize(50, 50); } -QSize ButtonDefence::minimumSizeHint() const +QSize DeviceButton::minimumSizeHint() const { return QSize(10, 10); } -void ButtonDefence::checkAlarm() +void DeviceButton::checkAlarm() { if (isDark) { - imgName = QString(":/image/buttondefence/btn_defence_error_%1.png").arg(type); + imgName = QString(":/image/devicebutton/devicebutton_black_%1.png").arg(type); } else { - imgName = QString(":/image/buttondefence/btn_defence_alarm_%1.png").arg(type); + imgName = QString(":/image/devicebutton/devicebutton_red_%1.png").arg(type); } isDark = !isDark; this->update(); } -void ButtonDefence::setCanMove(bool canMove) +void DeviceButton::setCanMove(bool canMove) { this->canMove = canMove; } -void ButtonDefence::setText(const QString &text) +void DeviceButton::setText(const QString &text) { if (this->text != text) { this->text = text; @@ -164,7 +164,7 @@ void ButtonDefence::setText(const QString &text) } } -void ButtonDefence::setButtonStyle(const ButtonDefence::ButtonStyle &buttonStyle) +void DeviceButton::setButtonStyle(const DeviceButton::ButtonStyle &buttonStyle) { this->buttonStyle = buttonStyle; if (buttonStyle == ButtonStyle_Circle) { @@ -183,26 +183,26 @@ void ButtonDefence::setButtonStyle(const ButtonDefence::ButtonStyle &buttonStyle type = "circle"; } - setButtonStatus(buttonStatus); + setButtonColor(buttonColor); } -void ButtonDefence::setButtonStatus(const ButtonDefence::ButtonStatus &buttonStatus) +void DeviceButton::setButtonColor(const DeviceButton::ButtonColor &buttonColor) { - this->buttonStatus = buttonStatus; + this->buttonColor = buttonColor; isDark = false; if (timer->isActive()) { timer->stop(); } - if (buttonStatus == ButtonStatus_Arming) { - imgName = QString(":/image/buttondefence/btn_defence_arming_%1.png").arg(type); - } else if (buttonStatus == ButtonStatus_Disarming) { - imgName = QString(":/image/buttondefence/btn_defence_disarming_%1.png").arg(type); - } else if (buttonStatus == ButtonStatus_Bypass) { - imgName = QString(":/image/buttondefence/btn_defence_bypass_%1.png").arg(type); - } else if (buttonStatus == ButtonStatus_Error) { - imgName = QString(":/image/buttondefence/btn_defence_error_%1.png").arg(type); - } else if (buttonStatus == ButtonStatus_Alarm) { + if (buttonColor == ButtonColor_Green) { + imgName = QString(":/image/devicebutton/devicebutton_green_%1.png").arg(type); + } else if (buttonColor == ButtonColor_Blue) { + imgName = QString(":/image/devicebutton/devicebutton_blue_%1.png").arg(type); + } else if (buttonColor == ButtonColor_Gray) { + imgName = QString(":/image/devicebutton/devicebutton_gray_%1.png").arg(type); + } else if (buttonColor == ButtonColor_Black) { + imgName = QString(":/image/devicebutton/devicebutton_black_%1.png").arg(type); + } else if (buttonColor == ButtonColor_Red) { checkAlarm(); if (!timer->isActive()) { timer->start(); diff --git a/devicebutton/devicebutton.h b/devicebutton/devicebutton.h new file mode 100644 index 0000000..bc7c104 --- /dev/null +++ b/devicebutton/devicebutton.h @@ -0,0 +1,99 @@ +#ifndef DEVICEBUTTON_H +#define DEVICEBUTTON_H + +/** + * 设备按钮控件 作者:feiyangqingyun(QQ:517216493) 2018-7-2 + * 1. 可设置按钮样式 圆形、警察、气泡、气泡2、消息、消息2 + * 2. 可设置按钮颜色 布防、撤防、报警、旁路、故障 + * 3. 可设置报警切换 + * 4. 可设置显示的防区号 + * 5. 可设置是否可鼠标拖动 + * 6. 发出单击和双击信号 + */ + +#include + +#ifdef quc +class Q_DECL_EXPORT DeviceButton : public QWidget +#else +class DeviceButton : public QWidget +#endif + +{ + Q_OBJECT + Q_ENUMS(ButtonStyle) + Q_ENUMS(ButtonColor) + + Q_PROPERTY(bool canMove READ getCanMove WRITE setCanMove) + Q_PROPERTY(QString text READ getText WRITE setText) + + Q_PROPERTY(ButtonStyle buttonStyle READ getButtonStyle WRITE setButtonStyle) + Q_PROPERTY(ButtonColor buttonColor READ getButtonColor WRITE setButtonColor) + +public: + //设备按钮样式 + enum ButtonStyle { + ButtonStyle_Circle = 0, //圆形 + ButtonStyle_Police = 1, //警察 + ButtonStyle_Bubble = 2, //气泡 + ButtonStyle_Bubble2 = 3, //气泡2 + ButtonStyle_Msg = 4, //消息 + ButtonStyle_Msg2 = 5 //消息2 + }; + + //设备按钮颜色 + enum ButtonColor { + ButtonColor_Green = 0, //绿色 设备激活状态 + ButtonColor_Blue = 1, //蓝色 设备在线状态 + ButtonColor_Red = 2, //红色 设备报警状态 + ButtonColor_Gray = 3, //灰色 设备离线状态 + ButtonColor_Black = 4 //黑色 设备故障状态 + }; + + explicit DeviceButton(QWidget *parent = 0); + ~DeviceButton(); + +protected: + void paintEvent(QPaintEvent *); + bool eventFilter(QObject *watched, QEvent *event); + +private: + bool canMove; //是否可移动 + QString text; //显示文字 + ButtonStyle buttonStyle; //按钮样式 + ButtonColor buttonColor; //按钮颜色 + + QString type; //图片末尾类型 + QString imgName; //背景图片名称 + bool isDark; //是否加深报警 + QTimer *timer; //报警闪烁定时器 + +private slots: + void checkAlarm(); //切换报警状态 + +public: + bool getCanMove() const; + QString getText() const; + + ButtonStyle getButtonStyle() const; + ButtonColor getButtonColor() const; + + QSize sizeHint() const; + QSize minimumSizeHint() const; + +public Q_SLOTS: + //设置可移动 + void setCanMove(bool canMove); + //设置显示文字 + void setText(const QString &text); + //设置样式 + void setButtonStyle(const ButtonStyle &buttonStyle); + //设置颜色 + void setButtonColor(const ButtonColor &buttonColor); + +Q_SIGNALS: + void clicked(); + void doubleClicked(); +}; + +#endif //DEVICEBUTTON_H diff --git a/buttondefence/buttondefence.pro b/devicebutton/devicebutton.pro similarity index 63% rename from buttondefence/buttondefence.pro rename to devicebutton/devicebutton.pro index c0699cc..cbd4038 100644 --- a/buttondefence/buttondefence.pro +++ b/devicebutton/devicebutton.pro @@ -8,18 +8,18 @@ QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -TARGET = buttondefence +TARGET = devicebutton TEMPLATE = app DESTDIR = $$PWD/../bin CONFIG += warn_off SOURCES += main.cpp -SOURCES += frmbuttondefence.cpp -SOURCES += buttondefence.cpp +SOURCES += frmdevicebutton.cpp +SOURCES += devicebutton.cpp -HEADERS += frmbuttondefence.h -HEADERS += buttondefence.h +HEADERS += frmdevicebutton.h +HEADERS += devicebutton.h -FORMS += frmbuttondefence.ui +FORMS += frmdevicebutton.ui RESOURCES += main.qrc diff --git a/devicebutton/frmdevicebutton.cpp b/devicebutton/frmdevicebutton.cpp new file mode 100644 index 0000000..7d8da86 --- /dev/null +++ b/devicebutton/frmdevicebutton.cpp @@ -0,0 +1,71 @@ +#include "frmdevicebutton.h" +#include "ui_frmdevicebutton.h" +#include "devicebutton.h" +#include "qdebug.h" + +frmDeviceButton::frmDeviceButton(QWidget *parent) : QWidget(parent), ui(new Ui::frmDeviceButton) +{ + ui->setupUi(this); + this->initForm(); +} + +frmDeviceButton::~frmDeviceButton() +{ + delete ui; +} + +void frmDeviceButton::initForm() +{ + //设置背景地图 + ui->labMap->setStyleSheet("border-image:url(:/image/bg_call.jpg);"); + + btn1 = new DeviceButton(ui->labMap); + btn1->setText("#1"); + btn1->setGeometry(5, 5, 35, 35); + + btn2 = new DeviceButton(ui->labMap); + btn2->setText("#2"); + btn2->setGeometry(45, 5, 35, 35); + + btn3 = new DeviceButton(ui->labMap); + btn3->setText("#3"); + btn3->setGeometry(85, 5, 35, 35); + + btnStyle << ui->btnCircle << ui->btnPolice << ui->btnBubble << ui->btnBubble2 << ui->btnMsg << ui->btnMsg2; + foreach (QPushButton *btn, btnStyle) { + connect(btn, SIGNAL(clicked(bool)), this, SLOT(changeStyle())); + } + + btnColor << ui->btnGreen << ui->btnBlue << ui->btnRed << ui->btnGray << ui->btnBlack; + foreach (QPushButton *btn, btnColor) { + connect(btn, SIGNAL(clicked(bool)), this, SLOT(changeColor())); + } +} + +void frmDeviceButton::changeStyle() +{ + QPushButton *btn = (QPushButton *)sender(); + int index = btnStyle.indexOf(btn); + DeviceButton::ButtonStyle style = (DeviceButton::ButtonStyle)index; + btn1->setButtonStyle(style); + btn2->setButtonStyle(style); + btn3->setButtonStyle(style); +} + +void frmDeviceButton::changeColor() +{ + QPushButton *btn = (QPushButton *)sender(); + int index = btnColor.indexOf(btn); + DeviceButton::ButtonColor style = (DeviceButton::ButtonColor)index; + btn1->setButtonColor(style); + btn2->setButtonColor(style); + btn3->setButtonColor(style); +} + +void frmDeviceButton::on_ckCanMove_stateChanged(int arg1) +{ + bool canMove = (arg1 != 0); + btn1->setCanMove(canMove); + btn2->setCanMove(canMove); + btn3->setCanMove(canMove); +} diff --git a/devicebutton/frmdevicebutton.h b/devicebutton/frmdevicebutton.h new file mode 100644 index 0000000..b8b45ca --- /dev/null +++ b/devicebutton/frmdevicebutton.h @@ -0,0 +1,36 @@ +#ifndef FRMDEVICEBUTTON_H +#define FRMDEVICEBUTTON_H + +#include + +class DeviceButton; +class QPushButton; + +namespace Ui { +class frmDeviceButton; +} + +class frmDeviceButton : public QWidget +{ + Q_OBJECT + +public: + explicit frmDeviceButton(QWidget *parent = 0); + ~frmDeviceButton(); + +private slots: + void initForm(); + void changeStyle(); + void changeColor(); + void on_ckCanMove_stateChanged(int arg1); + +private: + Ui::frmDeviceButton *ui; + DeviceButton *btn1; + DeviceButton *btn2; + DeviceButton *btn3; + QList btnStyle; + QList btnColor; +}; + +#endif // FRMDEVICEBUTTON_H diff --git a/buttondefence/frmbuttondefence.ui b/devicebutton/frmdevicebutton.ui similarity index 87% rename from buttondefence/frmbuttondefence.ui rename to devicebutton/frmdevicebutton.ui index 5e914fc..4470065 100644 --- a/buttondefence/frmbuttondefence.ui +++ b/devicebutton/frmdevicebutton.ui @@ -1,7 +1,7 @@ - frmButtonDefence - + frmDeviceButton + 0 @@ -95,37 +95,37 @@ - + - 布防 + 绿色 - + - 撤防 + 蓝色 - + - 报警 + 红色 - + - 旁路 + 灰色 - + - 故障 + 黑色 diff --git a/buttondefence/image/bg_call.jpg b/devicebutton/image/bg_call.jpg similarity index 100% rename from buttondefence/image/bg_call.jpg rename to devicebutton/image/bg_call.jpg diff --git a/buttondefence/image/buttondefence/btn_defence_error_bubble.png b/devicebutton/image/devicebutton/devicebutton_black_bubble.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_bubble.png rename to devicebutton/image/devicebutton/devicebutton_black_bubble.png diff --git a/buttondefence/image/buttondefence/btn_defence_error_bubble2.png b/devicebutton/image/devicebutton/devicebutton_black_bubble2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_bubble2.png rename to devicebutton/image/devicebutton/devicebutton_black_bubble2.png diff --git a/buttondefence/image/buttondefence/btn_defence_error_circle.png b/devicebutton/image/devicebutton/devicebutton_black_circle.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_circle.png rename to devicebutton/image/devicebutton/devicebutton_black_circle.png diff --git a/buttondefence/image/buttondefence/btn_defence_error_msg.png b/devicebutton/image/devicebutton/devicebutton_black_msg.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_msg.png rename to devicebutton/image/devicebutton/devicebutton_black_msg.png diff --git a/buttondefence/image/buttondefence/btn_defence_error_msg2.png b/devicebutton/image/devicebutton/devicebutton_black_msg2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_msg2.png rename to devicebutton/image/devicebutton/devicebutton_black_msg2.png diff --git a/buttondefence/image/buttondefence/btn_defence_error_police.png b/devicebutton/image/devicebutton/devicebutton_black_police.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_error_police.png rename to devicebutton/image/devicebutton/devicebutton_black_police.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_bubble.png b/devicebutton/image/devicebutton/devicebutton_blue_bubble.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_bubble.png rename to devicebutton/image/devicebutton/devicebutton_blue_bubble.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_bubble2.png b/devicebutton/image/devicebutton/devicebutton_blue_bubble2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_bubble2.png rename to devicebutton/image/devicebutton/devicebutton_blue_bubble2.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_circle.png b/devicebutton/image/devicebutton/devicebutton_blue_circle.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_circle.png rename to devicebutton/image/devicebutton/devicebutton_blue_circle.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_msg.png b/devicebutton/image/devicebutton/devicebutton_blue_msg.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_msg.png rename to devicebutton/image/devicebutton/devicebutton_blue_msg.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_msg2.png b/devicebutton/image/devicebutton/devicebutton_blue_msg2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_msg2.png rename to devicebutton/image/devicebutton/devicebutton_blue_msg2.png diff --git a/buttondefence/image/buttondefence/btn_defence_disarming_police.png b/devicebutton/image/devicebutton/devicebutton_blue_police.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_disarming_police.png rename to devicebutton/image/devicebutton/devicebutton_blue_police.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_bubble.png b/devicebutton/image/devicebutton/devicebutton_gray_bubble.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_bubble.png rename to devicebutton/image/devicebutton/devicebutton_gray_bubble.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_bubble2.png b/devicebutton/image/devicebutton/devicebutton_gray_bubble2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_bubble2.png rename to devicebutton/image/devicebutton/devicebutton_gray_bubble2.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_circle.png b/devicebutton/image/devicebutton/devicebutton_gray_circle.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_circle.png rename to devicebutton/image/devicebutton/devicebutton_gray_circle.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_msg.png b/devicebutton/image/devicebutton/devicebutton_gray_msg.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_msg.png rename to devicebutton/image/devicebutton/devicebutton_gray_msg.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_msg2.png b/devicebutton/image/devicebutton/devicebutton_gray_msg2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_msg2.png rename to devicebutton/image/devicebutton/devicebutton_gray_msg2.png diff --git a/buttondefence/image/buttondefence/btn_defence_bypass_police.png b/devicebutton/image/devicebutton/devicebutton_gray_police.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_bypass_police.png rename to devicebutton/image/devicebutton/devicebutton_gray_police.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_bubble.png b/devicebutton/image/devicebutton/devicebutton_green_bubble.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_bubble.png rename to devicebutton/image/devicebutton/devicebutton_green_bubble.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_bubble2.png b/devicebutton/image/devicebutton/devicebutton_green_bubble2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_bubble2.png rename to devicebutton/image/devicebutton/devicebutton_green_bubble2.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_circle.png b/devicebutton/image/devicebutton/devicebutton_green_circle.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_circle.png rename to devicebutton/image/devicebutton/devicebutton_green_circle.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_msg.png b/devicebutton/image/devicebutton/devicebutton_green_msg.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_msg.png rename to devicebutton/image/devicebutton/devicebutton_green_msg.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_msg2.png b/devicebutton/image/devicebutton/devicebutton_green_msg2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_msg2.png rename to devicebutton/image/devicebutton/devicebutton_green_msg2.png diff --git a/buttondefence/image/buttondefence/btn_defence_arming_police.png b/devicebutton/image/devicebutton/devicebutton_green_police.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_arming_police.png rename to devicebutton/image/devicebutton/devicebutton_green_police.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_bubble.png b/devicebutton/image/devicebutton/devicebutton_red_bubble.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_bubble.png rename to devicebutton/image/devicebutton/devicebutton_red_bubble.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_bubble2.png b/devicebutton/image/devicebutton/devicebutton_red_bubble2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_bubble2.png rename to devicebutton/image/devicebutton/devicebutton_red_bubble2.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_circle.png b/devicebutton/image/devicebutton/devicebutton_red_circle.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_circle.png rename to devicebutton/image/devicebutton/devicebutton_red_circle.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_msg.png b/devicebutton/image/devicebutton/devicebutton_red_msg.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_msg.png rename to devicebutton/image/devicebutton/devicebutton_red_msg.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_msg2.png b/devicebutton/image/devicebutton/devicebutton_red_msg2.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_msg2.png rename to devicebutton/image/devicebutton/devicebutton_red_msg2.png diff --git a/buttondefence/image/buttondefence/btn_defence_alarm_police.png b/devicebutton/image/devicebutton/devicebutton_red_police.png similarity index 100% rename from buttondefence/image/buttondefence/btn_defence_alarm_police.png rename to devicebutton/image/devicebutton/devicebutton_red_police.png diff --git a/buttondefence/main.cpp b/devicebutton/main.cpp similarity index 87% rename from buttondefence/main.cpp rename to devicebutton/main.cpp index b0b2855..0ab185b 100644 --- a/buttondefence/main.cpp +++ b/devicebutton/main.cpp @@ -1,6 +1,6 @@ #pragma execution_character_set("utf-8") -#include "frmbuttondefence.h" +#include "frmdevicebutton.h" #include #include @@ -23,8 +23,8 @@ int main(int argc, char *argv[]) QTextCodec::setCodecForLocale(codec); #endif - frmButtonDefence w; - w.setWindowTitle("防区按钮控件"); + frmDeviceButton w; + w.setWindowTitle("设备按钮控件"); w.show(); return a.exec(); diff --git a/devicebutton/main.qrc b/devicebutton/main.qrc new file mode 100644 index 0000000..07d37f5 --- /dev/null +++ b/devicebutton/main.qrc @@ -0,0 +1,35 @@ + + + image/bg_call.jpg + image/devicebutton/devicebutton_black_bubble.png + image/devicebutton/devicebutton_black_bubble2.png + image/devicebutton/devicebutton_black_circle.png + image/devicebutton/devicebutton_black_msg.png + image/devicebutton/devicebutton_black_msg2.png + image/devicebutton/devicebutton_black_police.png + image/devicebutton/devicebutton_blue_bubble.png + image/devicebutton/devicebutton_blue_bubble2.png + image/devicebutton/devicebutton_blue_circle.png + image/devicebutton/devicebutton_blue_msg.png + image/devicebutton/devicebutton_blue_msg2.png + image/devicebutton/devicebutton_blue_police.png + image/devicebutton/devicebutton_gray_bubble.png + image/devicebutton/devicebutton_gray_bubble2.png + image/devicebutton/devicebutton_gray_circle.png + image/devicebutton/devicebutton_gray_msg.png + image/devicebutton/devicebutton_gray_msg2.png + image/devicebutton/devicebutton_gray_police.png + image/devicebutton/devicebutton_green_bubble.png + image/devicebutton/devicebutton_green_bubble2.png + image/devicebutton/devicebutton_green_circle.png + image/devicebutton/devicebutton_green_msg.png + image/devicebutton/devicebutton_green_msg2.png + image/devicebutton/devicebutton_green_police.png + image/devicebutton/devicebutton_red_bubble.png + image/devicebutton/devicebutton_red_bubble2.png + image/devicebutton/devicebutton_red_circle.png + image/devicebutton/devicebutton_red_msg.png + image/devicebutton/devicebutton_red_msg2.png + image/devicebutton/devicebutton_red_police.png + + diff --git a/web/video_system.html b/web/video_system.html index 42a246e..97f5e1c 100644 --- a/web/video_system.html +++ b/web/video_system.html @@ -684,8 +684,8 @@ header, .context-menu, .megamenu-content, footer{ Qt编写的视频监控系统开发及使用说明
-
  • 0 前言说明

    0.1 系统说明

    1. 本视频监控系统做的是通用的系统,主要偏重UI和整体框架。
    2. 主要功能包括摄像机管理,实时视频显示,设备地图显示,各种画面切换,onvif搜索设备和云台控制,通用的NVR视频流播放(比如海康的NVR支持直接取流回放)等功能。
    3. 如果是依赖SDK去实现的功能(雨刷、去雾等)都没有做,那个破坏了兼容性,无法通用其他摄像机设备以及其他操作系统。
    4. 一般都是买过去自己加上SDK的功能和自己定制的需要的功能。
    5. 每个厂家SDK和定制的功能都不一样。
    6. 本程序会不定期更新,包括使用说明,购买者可永久免费升级,一次购买终生售后。

    0.2 特别说明

    1. 程序本身是个客户端并不是服务器程序。
    2. 摄像机管理没有限制摄像机的数量,理论上10000路肯定没有问题,就是个数据库记录。
    3. 实时显示具体能支持多少路,和具体的电脑配置有关(亲测1.8G主频8G内存I5子码流64路,总之比海康大华客户端要更优秀)。
    4. 程序实时显示界面最大可以到64路,每个通道都是打开的时候才会去建立连接取视频流,而不是一开始就建立了连接。
    5. 未经本人许可不可将本项目源码扩散,如有发现本人将追究法律责任,谢谢配合。

    相关站点

    1. 国内站点:https://gitee.com/feiyangqingyun/
    2. 国际站点:https://github.com/feiyangqingyun/
    3. 个人主页:https://blog.csdn.net/feiyangqingyun/
    4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun
    5. 产品主页:https://blog.csdn.net/feiyangqingyun/article/details/97565652

    0.3 功能特点

    0.3.1 软件模块

    1. 视频监控模块,各种停靠小窗体子模块,包括设备列表、图文警情、窗口信息、云台控制、预置位、巡航设置、设备控制、悬浮地图、网页浏览等。
    2. 视频回放模块,包括本地回放、远程回放、设备播放、图片回放、视频上传等。
    3. 电子地图模块,包括图片地图、在线地图、离线地图、路径规划等。
    4. 日志查询模块,包括本地日志、设备日志等。
    5. 系统设置模块,包括系统设置(基本设置、视频参数、数据库设置、地图配置、串口配置等)、录像机管理、摄像机管理、轮询配置、用户管理等。

    0.3.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协议,包括设备搜索、云台控制、设备控制(图片参数、校对时间、系统重启,抓拍图片等)。
    6. 支持权限管理,不同的用户可以对应不同的模块权限,比如删除日志、关闭系统等。
    7. 数据库支持多种,包括sqlite、mysql、sqlserver、postgresql、oracle、人大金仓等。
    8. 本地USB摄像机支持设置分辨率、帧率等参数。
    9. 所有停靠模块都自动生成对应的菜单用来控制显示和隐藏,在标题栏右键可以弹出。
    10. 支持显示所有模块、隐藏所有模块、复位普通布局、复位全屏布局。
    11. 双击设备弹出实时预览视频,支持图片地图、在线地图、离线地图等。
    12. 摄像机节点拖曳到对应窗体播放视频,同时支持拖曳本地文件直接播放。
    13. 删除视频支持鼠标右键删除、悬浮条关闭删除、拖曳到视频监控面板外删除等多种方式。
    14. 图片地图上设备按钮可自由拖动,自动保存位置信息。百度地图上可以鼠标单击获取经纬度信息,用来更新设备位置。
    15. 视频监控面板窗体中任意通道支持拖曳交换,瞬间响应。
    16. 封装了百度地图,视图切换,运动轨迹,设备点位,鼠标按下获取经纬度等。
    17. 双击节点、拖曳节点、拖曳窗体交换位置等操作,均自动更新保存最后的播放地址,下次软件打开自动应用。
    18. 右下角音量条控件,失去焦点自动隐藏,音量条带静音图标。
    19. 支持视频截图,可指定单个或者对所有通道截图,底部小工具栏也有截图按钮。
    20. 支持超时自动隐藏鼠标指针、自动全屏机制。
    21. 支持onvif云台控制,可上下左右移动云台摄像机,包括复位和焦距调整等。
    22. 支持任意onvif摄像机,包括但不限于海康、大华、宇视、天地伟业、华为等。
    23. 可保存视频,可选定时存储或者单文件存储,可选存储间隔时间。
    24. 可设置视频流通信方式tcp+udp,可设置视频解码是速度优先、质量优先、均衡等。
    25. 可设置软件中文名称、英文名称、LOGO图标等。
    26. 存储的视频文件支持导出到指定目录,支持批量上传到服务器。

    0.3.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绘制视频,超低的CPU资源占用,支持yuyv和nv12两种格式绘制,很牛逼。
    15. 高度可定制化,用户可以很方便的在此基础上衍生自己的功能,比如增加自定义模块,增加运行模式、机器人监控、无人机监控、挖掘机监控、检察院审判监控等。
    16. 支持xp、win7、win10、linux、mac、各种国产系统(UOS、中标麒麟、银河麒麟等)、嵌入式linux等系统。
    17. 注释完整,项目结构清晰,超级详细完整的使用开发手册,精确到每个代码文件的功能说明,不断持续迭代版本。

    0.4 编译说明

    0.4.1 版本说明

    1. 本系统没有说基于哪个Qt版本,由于系统中电子地图模块用到了浏览器模块,所以理论上要求你电脑的Qt版本也有浏览器模块才行
    2. windows上Qt5.6以上的版本需要msvc编译器的版本才有,其余系统都会有。
    3. 如果没有则电子地图模块不可用,但是其余功能全部可用没有任何影响。
    4. 本人亲测4.7、4.8、5.5、5.6、5.7、5.9、5.12、5.13、5.14、5.15等。
    5. 2021-1-6开始集成了miniblink浏览器内核,意味着mingw版本的qt5.6以上版本也全部支持,这样就所有系统都有浏览器模块不需要担心没有电子地图的问题。

    0.4.2 注意事项

    1. 可执行文件在源码同级目录的bin目录下。
    2. 编译完成后记得将源码下的file文件夹下的所有文件复制到可执行文件同一目录。
    3. 如果开启了视频监控(默认开启),则记得将对应的动态库文件复制到可执行文件同一目录。比如采用ffmpeg内核(默认就是ffmpeg)的话,则将下载到的dll_ffmpeg4下的所有文件复制到可执行文件同一目录。
    4. 各个操作系统的ffmpeg和vlc编译好的dll以及miniblink的dll下载地址。 -https://pan.baidu.com/s/13LDRu6mXC6gaADtrGprNVA  提取码: ujm7。
    5. 如果是64位的qt则对应的dll时候拷贝dll_ffmpeg4_64目录下的。
    6. 如果使用的ffmpeg3则对应dll目录就是dll_ffmpeg,在ffmpeg.pri文件中可以看到具体启用的是ffmpeg3(支持XP)还是ffmpeg4(不支持XP),默认是ffmpeg4。
    7. 图形字体对照表在doc目录下的IconFont.png、Font Awesome Cheatsheet.png,分别对应图形字体类 IconFont、IconHelper。
    8. 如果发现地图打不开,请先确认file目录下的所有文件有没有拷贝过去。
    9. 如果是用vs+qt可能报错 error LNK2026,解决办法详细见文档中其他说明。
    10. 默认用户名admin 密码admin

    0.4.3 离线地图

    1. 离线地图可以用网上的瓦片地图下载器下载百度的离线地图放到对应目录即可。
    2. 也可以直接下载网盘中已经下载好的上海市的离线地图。
    3. 下载地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取密码:01jf 文件名称:bin_map_tiles.zip

    使用说明

    1. 将压缩包下的两个文件夹复制到对应可执行文件下的config文件夹下,和map.js文件同一级目录。
    2. tiles文件夹是街道图,tiles_hybrid文件夹是卫星图。
    3. 默认提供的是上海市徐汇区的瓦片地图,如果自己用万能地图下载器下载的百度地图的瓦片文件,也可以对应替换就行。
    4. 要注意的是格式,默认是jpg,如果下载的瓦片地图格式是png则需要打开config文件夹下的map_load.js文件,将.jpg改成.png保存即可。

    0.5 视频格式

    0.5.1 USB摄像头

    1. 内核ffmpeg写法:video=USB2.0 PC CAMERA(具体要看设备名)。
    2. 内核vlc写法:dshow://:dshow-vdev='Default' (或者填USB2.0 PC CAMERA)
    3. 带参数写法:2020-12-12以后增加USB摄像头直接url带分辨率帧率写法,默认分辨率640x480。

    写法举例

    1. video=USB2.0 PC CAMERA|1920x1080|30(表示1920*1080分辨率30帧)
    2. video=USB2.0 PC CAMERA|640x480(表示640*480分辨率)
    3. dshow://:dshow-vdev='Default'|1920x1080(vlc内核1920*1080分辨率)

    0.5.2 网络地址

    1. 下面的地址有时候会失效,可以自行网上找找其他的地址,网络视频地址建议在晚上测试会更流畅。
    2. 大雄兔:rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
    3. 中央卫视:rtmp://58.200.131.2:1935/livetv/cctv1 – cctv10
    4. 海康萤石:https://hls01open.ys7.com/openlive/6e0b2be040a943489ef0b9bb344b96b8.hd.m3u8
    5. 摄像机格式:https://blog.csdn.net/qq_38880380/article/details/80652697

    0.5.3 视频文件

    1. http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4
    2. http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4
    3. http://vfx.mtime.cn/Video/2019/03/17/mp4/190317150237409904.mp4
    4. http://vfx.mtime.cn/Video/2019/03/14/mp4/190314223540373995.mp4

    0.6 版本说明

    V20210425

    1. 配置文件密码改成密文存储。
    2. 增加了无敌的牛逼的万能的完美入微级自动分页导航控件。
    3. 日志记录表增加索引,速度提升100倍以上。
    4. 新增多个设备轨迹 不同颜色+传入经纬度 单独示例。
    5. 对地图核心类所有覆盖物都增加颜色+粗细+透明度的参数,可动态传入对应值。
    6. 系统设置增加用户管理模块,可分别设置对应的权限。
    7. 万能权限管理算法,通过设置不同需要授权的模块名称,对应切换的按钮自动计算。
    8. 增加了appkey秘钥类,用于校验秘钥是否正确,运行时间等。

    V20210403

    1. 增加全局变量AppData::LastLiveTime,记住程序最后的活动时间-包括键盘+鼠标活动,用于两个判断,一个是超过多久没有操作全屏下隐藏鼠标光标,一个是超过多久没有操作如果没有全屏则自动全屏。
    2. 增加App::TimeAutoFull配置参数用来判断比较超时自动全屏。
    3. 重命名为TimeHideCursor表示程序多久未操作自动隐藏光标,TimeAutoFull程序多久未操作自动全屏界面,下拉框选项值增加0,表示不启用此功能。
    4. 增加信息列表模块frmMsgList,用于图文列表显示信息,对应兄弟类frmMsgTable用于表格显示消息。
    5. 大改版,将中间部分全部改成了QMainWindow,子模块全部采用停靠窗体,可以悬浮半透明,自动记忆每个模块的最后的位置,启动后自动应用。
    6. 移除大改版后的所有不需要用的变量和配置参数,重新调整配置参数。
    7. 增加透明度参数用于停靠窗体独立出来后的透明度。
    8. 将摄像机控制部分比如云台+控制+预置位+巡航,单独分类到ipc模块,方便管理。
    9. 限定操作员不能移动停靠窗体等,需要管理员设计好。
    10. 修复系统设置中工作模式等切换造成的自动重启会弹出退出和登录两个窗体的BUG。
    11. 修复自动登录用户计算不正确的BUG,要以最后登录的用户为准。

    V20210322

    1. USB摄像头增加参数帧率,第二个参数是分辨率,第三个参数为帧率,不设置则采用默认的帧率,video=USB2.0 PC CAMERA|1920x1080|25。
    2. 增加独立的demo模块,专门用于测试监控系统中用到的组件和控件,演示如何使用,比如视频图片界面演示从文件夹读取图片绘制到窗体,视频窗体演示系统的核心组件视频控件的设置参数如何使用等。
    3. 增加了对其他数据库的支持,比如posgres、oracle、odbc、kingbase等数据库,理论上只要支持odbc数据源方式的都支持。
    4. 增加IndexStart启动窗体索引配置参数,0-主程序 1-演示示例。

    V20210305

    1. 修复数据库有时候没加载到的BUG。
    2. 新增配置参数控制画面切换的菜单和快捷图标是否显示。
    3. ffmpeg内核增加了可动态保存机制,点击开始保存按钮启动保存,单击结束则生成视频文件,如此往复。
    4. 海康内核判断主码流子码流改成了 /101? 和 /main/ 同时判断。
    5. 新增多屏幕的支持,自动在对应屏幕最大化全屏,对话框位置,右下角提示框等。
    6. 再次分类存放代码文件,分成core ui class三大类。
    7. 系统配置更改视频控件参数,统一一个函数设置,initCommonVideoWidget函数中做了过滤,必须关闭状态的视频控件设置才起作用。
    8. 设备播放模块增加大华NVR的远程回放地址,其他地址计算算法调整。
    9. 新增界面模块功能启用配置参数。
    10. 新增主界面顶部导航模块中间界面,用于不同的运行模式加载不同的模块。

    V20201212

    1. 增加USB摄像机分辨率设置,直接url带掉。
    2. 所有地图内核公用一个,复用代码。
    3. 增加地图默认级别和中心点坐标设置参数。
    4. 主界面四个模块独立出来,做成了可配置,这样后期可以任意位置放置自定义模块。
    5. 四个模块标题栏自定义。
    6. vlc内核和mpv内核的离线判断,当句柄模式下,统一为getLastTime,当调用该函数的时候自动查询播放状态,如果正在播放则自动更新时间为当前时间。
    7. 将各种在代码中define定义不同内核的代码全部优化,统一为一个类,很大减少代码量,统一为CommonVideoWidget和CommonVideoManage类。

    V20201108

    1. 轮询点模块增加批量生成功能。
    2. 录像机、摄像机、轮询点,增加导入导出功能。
    3. ffmpeg内核增加读取帧回调,超时识别,可以快速识别掉线。

    V20200828

    1. 增加了云台控制过滤,没有打开的视频禁用云台。
    2. linux上全屏BUG修复,采用showfullscreen。
    3. 增加轮询点管理模块。
    4. 修正轮询的可能崩溃的BUG。

    V20200730

    1. 系统设置增加了视频上传模块,用来将本地的视频文件传输到服务器,多线程并发。
    2. 视频监控内核新增MPV内核,修正了其他内核的部分函数和处理。
    3. 海康内核进行大改动,同时支持视频流和本地MP4文件播放,自动分析切换。
    4. 海康内核增加回调处理,可以拿到每一张图片。
    5. 海康内核进行了linux上的实验,可以正常播放。
    6. ffmpeg内核增加保存到MP4。
    7. 本地文件回放vlc部分增加进度切换等。
    8. 悬浮条关闭按钮增加实际处理,之前只是打印消息。
    9. 改进了vlc和mpv的事件回调机制,使其同时支持qt4+qt5。

    V20200620

    1. 增加了opengl显示实时视频,CPU占用极低。
    2. 增加了地图上设备点位置的调整。
    3. 设备点双击弹出实时视频预览。
    4. 增加GPS运动轨迹显示。
    5. ffmpeg解码类增加了音频播放,采用的QAudioOutput。

    V20191105

    1. 增加云台控制功能,可以上下左右等八个方位控制云台,默认采用相对移动,云台中间按下表示复位。
    2. 系统设置增加码流类型选择,默认子码流,切换完自动应用。
    3. 云台控制增加速度功能,值越大,速度越快。
    4. 增加焦距控制,可放大缩小,速度也可控制。

    1 用户登录退出

    1.1 用户登录

    +

  • 0 前言说明

    0.1 系统说明

    1. 本视频监控系统做的是通用的系统,主要偏重UI和整体框架。
    2. 主要功能包括摄像机管理,实时视频显示,设备地图显示,各种画面切换,onvif搜索设备和云台控制,通用的NVR视频流播放(比如海康的NVR支持直接取流回放)等功能。
    3. 如果是依赖SDK去实现的功能(雨刷、去雾等)都没有做,那个破坏了兼容性,无法通用其他摄像机设备以及其他操作系统。
    4. 一般都是买过去自己加上SDK的功能和自己定制的需要的功能。
    5. 每个厂家SDK和定制的功能都不一样。
    6. 本程序会不定期更新,包括使用说明,购买者可永久免费升级,一次购买终生售后。

    0.2 特别说明

    1. 程序本身是个客户端并不是服务器程序。
    2. 摄像机管理没有限制摄像机的数量,理论上10000路肯定没有问题,就是个数据库记录。
    3. 实时显示具体能支持多少路,和具体的电脑配置有关(亲测1.8G主频8G内存I5子码流64路,总之比海康大华客户端要更优秀)。
    4. 程序实时显示界面最大可以到64路,每个通道都是打开的时候才会去建立连接取视频流,而不是一开始就建立了连接。
    5. 未经本人许可不可将本项目源码扩散,如有发现本人将追究法律责任,谢谢配合。

    相关站点

    1. 国内站点:https://gitee.com/feiyangqingyun/
    2. 国际站点:https://github.com/feiyangqingyun/
    3. 个人主页:https://blog.csdn.net/feiyangqingyun/
    4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun
    5. 产品主页:https://blog.csdn.net/feiyangqingyun/article/details/97565652

    0.3 功能特点

    0.3.1 软件模块

    1. 视频监控模块,各种停靠小窗体子模块,包括设备列表、图文警情、窗口信息、云台控制、预置位、巡航设置、设备控制、悬浮地图、网页浏览等。
    2. 视频回放模块,包括本地回放、远程回放、设备播放、图片回放、视频上传等。
    3. 电子地图模块,包括图片地图、在线地图、离线地图、路径规划等。
    4. 日志查询模块,包括本地日志、设备日志等。
    5. 系统设置模块,包括系统设置(基本设置、视频参数、数据库设置、地图配置、串口配置等)、录像机管理、摄像机管理、轮询配置、用户管理等。

    0.3.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协议,包括设备搜索、云台控制、设备控制(图片参数、校对时间、系统重启,抓拍图片等)。
    6. 支持权限管理,不同的用户可以对应不同的模块权限,比如删除日志、关闭系统等。
    7. 数据库支持多种,包括sqlite、mysql、sqlserver、postgresql、oracle、人大金仓等。
    8. 本地USB摄像机支持设置分辨率、帧率等参数。
    9. 所有停靠模块都自动生成对应的菜单用来控制显示和隐藏,在标题栏右键可以弹出。
    10. 支持显示所有模块、隐藏所有模块、复位普通布局、复位全屏布局。
    11. 双击设备弹出实时预览视频,支持图片地图、在线地图、离线地图等。
    12. 摄像机节点拖曳到对应窗体播放视频,同时支持拖曳本地文件直接播放。
    13. 删除视频支持鼠标右键删除、悬浮条关闭删除、拖曳到视频监控面板外删除等多种方式。
    14. 图片地图上设备按钮可自由拖动,自动保存位置信息。百度地图上可以鼠标单击获取经纬度信息,用来更新设备位置。
    15. 视频监控面板窗体中任意通道支持拖曳交换,瞬间响应。
    16. 封装了百度地图,视图切换,运动轨迹,设备点位,鼠标按下获取经纬度等。
    17. 双击节点、拖曳节点、拖曳窗体交换位置等操作,均自动更新保存最后的播放地址,下次软件打开自动应用。
    18. 右下角音量条控件,失去焦点自动隐藏,音量条带静音图标。
    19. 支持视频截图,可指定单个或者对所有通道截图,底部小工具栏也有截图按钮。
    20. 支持超时自动隐藏鼠标指针、自动全屏机制。
    21. 支持onvif云台控制,可上下左右移动云台摄像机,包括复位和焦距调整等。
    22. 支持任意onvif摄像机,包括但不限于海康、大华、宇视、天地伟业、华为等。
    23. 可保存视频,可选定时存储或者单文件存储,可选存储间隔时间。
    24. 可设置视频流通信方式tcp+udp,可设置视频解码是速度优先、质量优先、均衡等。
    25. 可设置软件中文名称、英文名称、LOGO图标等。
    26. 存储的视频文件支持导出到指定目录,支持批量上传到服务器。

    0.3.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绘制视频,超低的CPU资源占用,支持yuyv和nv12两种格式绘制,很牛逼。
    15. 高度可定制化,用户可以很方便的在此基础上衍生自己的功能,比如增加自定义模块,增加运行模式、机器人监控、无人机监控、挖掘机监控、检察院审判监控等。
    16. 支持xp、win7、win10、linux、mac、各种国产系统(UOS、中标麒麟、银河麒麟等)、嵌入式linux等系统。
    17. 注释完整,项目结构清晰,超级详细完整的使用开发手册,精确到每个代码文件的功能说明,不断持续迭代版本。

    0.4 编译说明

    0.4.1 版本说明

    1. 本系统没有说基于哪个Qt版本,由于系统中电子地图模块用到了浏览器模块,所以理论上要求你电脑的Qt版本也有浏览器模块才行
    2. windows上Qt5.6以上的版本需要msvc编译器的版本才有,其余系统都会有。
    3. 如果没有则电子地图模块不可用,但是其余功能全部可用没有任何影响。
    4. 本人亲测4.7、4.8、5.5、5.6、5.7、5.9、5.12、5.13、5.14、5.15等。
    5. 2021-1-6开始集成了miniblink浏览器内核,意味着mingw版本的qt5.6以上版本也全部支持,这样就所有系统都有浏览器模块不需要担心没有电子地图的问题。

    0.4.2 注意事项

    1. 可执行文件在源码同级目录的bin目录下。
    2. 编译完成后记得将源码下的file文件夹下的所有文件复制到可执行文件同一目录。
    3. 如果开启了视频监控(默认开启),则记得将对应的动态库文件复制到可执行文件同一目录。比如采用ffmpeg内核(默认就是ffmpeg)的话,则将下载到的dll_ffmpeg4下的所有文件复制到可执行文件同一目录。
    4. 各个操作系统的ffmpeg和vlc编译好的dll以及miniblink的dll下载地址。 +https://pan.baidu.com/s/13LDRu6mXC6gaADtrGprNVA  提取码: ujm7。
    5. 如果是64位的qt则对应的dll时候拷贝dll_ffmpeg4_64目录下的。
    6. 如果使用的ffmpeg3则对应dll目录就是dll_ffmpeg,在ffmpeg.pri文件中可以看到具体启用的是ffmpeg3(支持XP)还是ffmpeg4(不支持XP),默认是ffmpeg4。
    7. 图形字体对照表在doc目录下的IconFont.png、Font Awesome Cheatsheet.png,分别对应图形字体类 IconFont、IconHelper。
    8. 如果发现地图打不开,请先确认file目录下的所有文件有没有拷贝过去。
    9. 如果是用vs+qt可能报错 error LNK2026,解决办法详细见文档中其他说明。
    10. 默认用户名admin 密码admin

    0.4.3 离线地图

    1. 离线地图可以用网上的瓦片地图下载器下载百度的离线地图放到对应目录即可。
    2. 也可以直接下载网盘中已经下载好的上海市的离线地图。
    3. 下载地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取密码:01jf 文件名称:bin_map_tiles.zip

    使用说明

    1. 将压缩包下的两个文件夹复制到对应可执行文件下的config文件夹下,和map.js文件同一级目录。
    2. tiles文件夹是街道图,tiles_hybrid文件夹是卫星图。
    3. 默认提供的是上海市徐汇区的瓦片地图,如果自己用万能地图下载器下载的百度地图的瓦片文件,也可以对应替换就行。
    4. 要注意的是格式,默认是jpg,如果下载的瓦片地图格式是png则需要打开config文件夹下的map_load.js文件,将.jpg改成.png保存即可。

    0.5 视频格式

    0.5.1 USB摄像头

    1. 内核ffmpeg写法:video=USB2.0 PC CAMERA(具体要看设备名)。
    2. 内核vlc写法:dshow://:dshow-vdev='Default' (或者填USB2.0 PC CAMERA)
    3. 带参数写法:2020-12-12以后增加USB摄像头直接url带分辨率帧率写法,默认分辨率640x480。

    写法举例

    1. video=USB2.0 PC CAMERA|1920x1080|30(表示1920*1080分辨率30帧)
    2. video=USB2.0 PC CAMERA|640x480(表示640*480分辨率)
    3. dshow://:dshow-vdev='Default'|1920x1080(vlc内核1920*1080分辨率)

    0.5.2 网络地址

    1. 下面的地址有时候会失效,可以自行网上找找其他的地址,网络视频地址建议在晚上测试会更流畅。
    2. 大雄兔:rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov
    3. 中央卫视:rtmp://58.200.131.2:1935/livetv/cctv1 – cctv10
    4. 海康萤石:https://hls01open.ys7.com/openlive/6e0b2be040a943489ef0b9bb344b96b8.hd.m3u8
    5. 摄像机格式:https://blog.csdn.net/qq_38880380/article/details/80652697

    0.5.3 视频文件

    1. http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4
    2. http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4
    3. http://vfx.mtime.cn/Video/2019/03/17/mp4/190317150237409904.mp4
    4. http://vfx.mtime.cn/Video/2019/03/14/mp4/190314223540373995.mp4

    0.6 版本说明

    V20210425

    1. 配置文件密码改成密文存储。
    2. 增加了无敌的牛逼的万能的完美入微级自动分页导航控件。
    3. 日志记录表增加索引,速度提升100倍以上。
    4. 新增多个设备轨迹 不同颜色+传入经纬度 单独示例。
    5. 对地图核心类所有覆盖物都增加颜色+粗细+透明度的参数,可动态传入对应值。
    6. 系统设置增加用户管理模块,可分别设置对应的权限。
    7. 万能权限管理算法,通过设置不同需要授权的模块名称,对应切换的按钮自动计算。
    8. 增加了appkey秘钥类,用于校验秘钥是否正确,运行时间等。

    V20210403

    1. 增加全局变量AppData::LastLiveTime,记住程序最后的活动时间-包括键盘+鼠标活动,用于两个判断,一个是超过多久没有操作全屏下隐藏鼠标光标,一个是超过多久没有操作如果没有全屏则自动全屏。
    2. 增加App::TimeAutoFull配置参数用来判断比较超时自动全屏。
    3. 重命名为TimeHideCursor表示程序多久未操作自动隐藏光标,TimeAutoFull程序多久未操作自动全屏界面,下拉框选项值增加0,表示不启用此功能。
    4. 增加信息列表模块frmMsgList,用于图文列表显示信息,对应兄弟类frmMsgTable用于表格显示消息。
    5. 大改版,将中间部分全部改成了QMainWindow,子模块全部采用停靠窗体,可以悬浮半透明,自动记忆每个模块的最后的位置,启动后自动应用。
    6. 移除大改版后的所有不需要用的变量和配置参数,重新调整配置参数。
    7. 增加透明度参数用于停靠窗体独立出来后的透明度。
    8. 将摄像机控制部分比如云台+控制+预置位+巡航,单独分类到ipc模块,方便管理。
    9. 限定操作员不能移动停靠窗体等,需要管理员设计好。
    10. 修复系统设置中工作模式等切换造成的自动重启会弹出退出和登录两个窗体的BUG。
    11. 修复自动登录用户计算不正确的BUG,要以最后登录的用户为准。

    V20210322

    1. USB摄像头增加参数帧率,第二个参数是分辨率,第三个参数为帧率,不设置则采用默认的帧率,video=USB2.0 PC CAMERA|1920x1080|25。
    2. 增加独立的demo模块,专门用于测试监控系统中用到的组件和控件,演示如何使用,比如视频图片界面演示从文件夹读取图片绘制到窗体,视频窗体演示系统的核心组件视频控件的设置参数如何使用等。
    3. 增加了对其他数据库的支持,比如posgres、oracle、odbc、kingbase等数据库,理论上只要支持odbc数据源方式的都支持。
    4. 增加IndexStart启动窗体索引配置参数,0-主程序 1-演示示例。

    V20210305

    1. 修复数据库有时候没加载到的BUG。
    2. 新增配置参数控制画面切换的菜单和快捷图标是否显示。
    3. ffmpeg内核增加了可动态保存机制,点击开始保存按钮启动保存,单击结束则生成视频文件,如此往复。
    4. 海康内核判断主码流子码流改成了 /101? 和 /main/ 同时判断。
    5. 新增多屏幕的支持,自动在对应屏幕最大化全屏,对话框位置,右下角提示框等。
    6. 再次分类存放代码文件,分成core ui class三大类。
    7. 系统配置更改视频控件参数,统一一个函数设置,initCommonVideoWidget函数中做了过滤,必须关闭状态的视频控件设置才起作用。
    8. 设备播放模块增加大华NVR的远程回放地址,其他地址计算算法调整。
    9. 新增界面模块功能启用配置参数。
    10. 新增主界面顶部导航模块中间界面,用于不同的运行模式加载不同的模块。

    V20201212

    1. 增加USB摄像机分辨率设置,直接url带掉。
    2. 所有地图内核公用一个,复用代码。
    3. 增加地图默认级别和中心点坐标设置参数。
    4. 主界面四个模块独立出来,做成了可配置,这样后期可以任意位置放置自定义模块。
    5. 四个模块标题栏自定义。
    6. vlc内核和mpv内核的离线判断,当句柄模式下,统一为getLastTime,当调用该函数的时候自动查询播放状态,如果正在播放则自动更新时间为当前时间。
    7. 将各种在代码中define定义不同内核的代码全部优化,统一为一个类,很大减少代码量,统一为CommonVideoWidget和CommonVideoManage类。

    V20201108

    1. 轮询点模块增加批量生成功能。
    2. 录像机、摄像机、轮询点,增加导入导出功能。
    3. ffmpeg内核增加读取帧回调,超时识别,可以快速识别掉线。

    20200828

    1. 增加了云台控制过滤,没有打开的视频禁用云台。
    2. linux上全屏BUG修复,采用showfullscreen。
    3. 增加轮询点管理模块。
    4. 修正轮询的可能崩溃的BUG。

    V20200730

    1. 系统设置增加了视频上传模块,用来将本地的视频文件传输到服务器,多线程并发。
    2. 视频监控内核新增MPV内核,修正了其他内核的部分函数和处理。
    3. 海康内核进行大改动,同时支持视频流和本地MP4文件播放,自动分析切换。
    4. 海康内核增加回调处理,可以拿到每一张图片。
    5. 海康内核进行了linux上的实验,可以正常播放。
    6. ffmpeg内核增加保存到MP4。
    7. 本地文件回放vlc部分增加进度切换等。
    8. 悬浮条关闭按钮增加实际处理,之前只是打印消息。
    9. 改进了vlc和mpv的事件回调机制,使其同时支持qt4+qt5。

    V20200620

    1. 增加了opengl显示实时视频,CPU占用极低。
    2. 增加了地图上设备点位置的调整。
    3. 设备点双击弹出实时视频预览。
    4. 增加GPS运动轨迹显示。
    5. ffmpeg解码类增加了音频播放,采用的QAudioOutput。

    V20191105

    1. 增加云台控制功能,可以上下左右等八个方位控制云台,默认采用相对移动,云台中间按下表示复位。
    2. 系统设置增加码流类型选择,默认子码流,切换完自动应用。
    3. 云台控制增加速度功能,值越大,速度越快。
    4. 增加焦距控制,可放大缩小,速度也可控制。

    1 用户登录退出

    1.1 用户登录

    系统默认开启了自动登录,可以在系统设置中将自动登录按钮关闭即可,可以在用户登录界面勾选记住密码和自动登录复选框,如果勾选了记住密码,则下次弹出的登录窗体会自动把最后一次的密码填进去,如果勾选了自动登录,则直接以上一次的用户登录到系统。

    1.2 用户退出

    如果开启了自动登录机制,在单击右上角的关闭按钮,会弹出用户退出窗体,需要输入密码才能退出,也可以在代码中屏蔽掉自动登录的判断,这样任何时候关闭系统都会弹出窗体要求输入密码来退出。用户登录和退出内置了超级密码 a ,在记不住密码或者密码丢失的时候使用。

    2 主界面操作

    @@ -694,8 +694,7 @@ header, .context-menu, .megamenu-content, footer{ 左侧和右侧的面板,可以通过单击面板右上角的关闭按钮来隐藏,当隐藏一个面板以后,剩余的面板会自动填充布局,如果需要重新显示面板,则在标题栏鼠标右键就可以对小面板进行显示和隐藏,右上角的时间和CPU显示面板可以在系统设置中控制显示隐藏。系统会自动记住最后的布局比如显示的面板和宽高占比,下次启动后自动应用。 特别说明

    1. 在停靠窗体的标题栏鼠标右键也会弹出子窗体的开启菜单,复选框勾选表示显示,悬浮的窗体没有这个特性,一定要是嵌入在主界面中的子窗体标题栏才有。
    2. 如果是全屏模式,由于没有了标题栏,想要关闭模块的话,需要将其拖动到边缘嵌入主窗体,然后在标题栏鼠标右键菜单中关闭即可。

    2.2 面板拖动

    面板和面板之间有个分隔条,鼠标移到对应分隔条的地方,会变成可拉动的鼠标指针,此时可以上下左右拉动调整宽高,调整好以后会自动保存宽高比例,下次启动后自动应用最后的配置来显示。

    2.3 视频播放

    视频播放同时支持多种方式:

    1. 双击子节点播放单个摄像机,在当前选中通道处播放。
    2. 双击父节点播放整个录像机的摄像机,依次排列。
    3. 按住子节点拖曳到对应通道,播放摄像机。
    4. 本地文件直接拖曳到通道,自动播放本地文件。
    5. 启动后自动播放最后通道的视频信息。

    2.4 视频截图

    在视频监控主界面,通道鼠标右键,会弹出右键菜单,选择截图当前视频或者截图所有视频,截图默认保存在可执行文件所在目录下的snap目录。视频面板底部工具栏也有截图按钮触发这个动作。 -文件名格式:Ch1_2020-07-30-13-41-24.png。

    2.5 删除视频

    -有多种方法可以删除视频:

    1. 鼠标右键删除当前视频。
    2. 鼠标右键删除所有视频。
    3. 按住通道画面移出视频监控画面。
    4. 悬浮条关闭按钮。

    2.6 画面切换

    系统支持多画面切换,全屏切换等,包括1+4+6+8+9+13+16+25+36+64画面切换,如果还需要增加更多的画面比如81+100等,可以直接在源码中稍微修改即可。

    1. 鼠标右键画面切换。
    2. 底部左侧画面切换缩略图。
    3. 快捷键alt+enter全屏。
    4. 快捷键esc退出全屏。

    64画面效果图

    2.7 声音调节

    +文件名格式:Ch1_2020-07-30-13-41-24.png。

    2.5 删除视频

    有多种方法可以删除视频:

    1. 鼠标右键删除当前视频。
    2. 鼠标右键删除所有视频。
    3. 按住通道画面移出视频监控画面。
    4. 悬浮条关闭按钮。

    2.6 画面切换

    系统支持多画面切换,全屏切换等,包括1+4+6+8+9+13+16+25+36+64画面切换,如果还需要增加更多的画面比如81+100等,可以直接在源码中稍微修改即可。

    1. 鼠标右键画面切换。
    2. 底部左侧画面切换缩略图。
    3. 快捷键alt+enter全屏。
    4. 快捷键esc退出全屏。

    64画面效果图

    2.7 声音调节

    在主界面画面栏右下角,按下声音图标自动弹出声音调节面板,失去焦点自动隐藏,拉动声音滚动条来调节声音大小,还有静音图标,声音调节目前做的是一个界面效果,并没有功能,具体功能自己实现,vlc内核和mpv内核已经封装了声音控制的接口函数。

    2.8 视频轮询

    视频轮询默认4画面轮询,如果需要其他画面,可以在系统设置中设置即可。 有两种方式可以启动视频轮询功能:

    1. 鼠标右键启动轮询。
    2. 画面右下角轮询按钮。

    2.9 通道交换

    通道交换功能很常用,一般用户喜欢调整自己想要的通道显示到前面或者占据画面的更大部分,比如6画面8画面的时候,左侧有一个画面占据很大的位置,一般这个用来显示重要性最高的实时视频,如果需要通道交换,则按住通道拖动到另外一个通道上面松开鼠标即可,会立即应用,瞬间切换,这里切记不要移出视频画面外,移出去表示删除。

    2.10 云台控制

    如果需要控制云台移动,先要选择对应的通道,边缘会高亮,进行云台控制的前提是该摄像机要是支持云台的摄像机,很多人以为啥摄像机都可以移动,这是错误的,如果摄像机不支持云台,这个功能就别玩了,玩不起,经常遇到一些人说怎么云台不能用了,一检查尼玛原来摄像机根本没有云台。

    @@ -703,9 +702,11 @@ header, .context-menu, .megamenu-content, footer{ 设备控制部分,目前可以获取和设置图片参数、手动校时、重启设备等,上面那一堆复选框对应功能需要用厂家sdk去实现,后期可能会增加一些onvif能够处理的功能。和云台控制操作一样,操作前也是需要选中某个通道,然后才是对选中的通道进行设备控制,比如图片参数中的明亮度、对比度、饱和度。

    2.12 报警订阅

    本系统默认支持海康摄像机的报警事件订阅,默认已经订阅,如果摄像机已经开启了报警事件的话,默认一般是关闭的,比如摄像机后面的开关量输入报警接口,需要web页面进去设置开启。报警订阅走的是onvif协议,默认测试过海康的摄像机,其余摄像机有些没有测试成功,后期会详细查下原因并改进,会持续更新完善。

    2.13 悬浮条操作

    本系统中将视频显示这块都封装成了一个控件,每个视频控件都有自己独立的悬浮条,悬浮条的位置可以自行修改两三行代码调整,默认悬浮条在顶部,自动拉伸填充显示,你也可以改成左侧右侧等位置显示,高度可调。悬浮条是一排按钮组成,具体按钮什么名称标识符和功能,可以自定义,控件的封装只是默认放了一排按钮,除了关闭按钮实现了功能外,其余都是信号的形式发出去的,具体操作由程序员本身根据不同的厂家来定义不同的功能。

    2.14 标签设置

    视频控件已经将OSD标签封装好了,默认提供两路OSD设置,每个OSD都可以设置是否启用、位置、文字内容、文字颜色、图片、文字大小等,这些设置都提供了友好的接口设置。

    在frmvideopanel.cpp文件中有设置示例,默认注释的,参数含义如下:

    1. 设置标签可见:setOSD1Visible
    2. 设置文字大小:setOSD1FontSize
    3. 设置文本文字:setOSD1Text
    4. 设置文字颜色:setOSD1Color
    5. 设置标签格式:setOSD1Format
    6. 设置标签位置:setOSD1Position

    3 视频回放

    视频回放中有多个子模块,分别是不同的含义:

    1. 本地回放:回放存储在本地电脑的视频文件。
    2. 远程回放:通过sdk方式回放NVR上的存储录像(暂未实现,每个厂家不一样)。
    3. 设备播放:通用的rtsp取流形式的播放实时视频和回放录像文件。
    4. 图片回放:查找对应文件夹下的所有通道图片,按照设定的间隔回复,类似视频效果,一般用在存储一堆图片序列的应用场景中。
    5. 视频上传:将查询的本地存储的视频文件上传到云端服务器。类似于将视频文件存储到服务器上,需要手动填写服务器地址和端口。

    3.1 本地回放

    3.1.1 视频查询

    -本地回放模块主要用来回放存储在本地电脑上的视频,先从右侧选择要回放的通道,默认是所有通道,然后选择类型:存储视频还是报警视频,默认选择存储视频(目前也只有存储的视频,没有报警视频,报警视频的规则还没定好,一般都是买过去自己定义),然后选择要查询的开始时间和结束时间,单击查询按钮,会自动列出来,双击对应的视频文件名称就会播放,除了查询按钮,其余按钮均没有实现具体功能。

    3.1.2 存储规则

    1. 默认存储主目录 video_normal
    2. 主目录下按照日期目录存放 比如 2021-04-07 2021-04-08
    3. 日期目录下是单个的视频文件 比如 Ch1_2021-04-07-14-08-11.mp4。
    4. 拓展功能可以存储对应的数据文件比如经纬度数据和视频文件一个目录 名称一样 拓展名可以是 txt

    3.1.3 视频下载

    视频下载是将查询出来的视频文件,按照勾选了的文件保存到选择的目录中。

    3.2 远程回放

    远程回放模块是用来通过sdk的形式回放远程NVR设备上的录像文件,这个暂未实现,本系统主要是为了兼容性和通用性,通过具体sdk形式调用的处理都没有做,破坏了移植性,到了其他平台就没法使用了,本系统sdk使用这块默认用的海康sdk作为示例。

    3.3 设备播放

    +本地回放模块主要用来回放存储在本地电脑上的视频,先从右侧选择要回放的通道,默认是所有通道,然后选择类型:存储视频还是报警视频,默认选择存储视频(目前也只有存储的视频,没有报警视频,报警视频的规则还没定好,一般都是买过去自己定义),然后选择要查询的开始时间和结束时间,单击查询按钮,会自动列出来,双击对应的视频文件名称就会播放,除了查询按钮,其余按钮均没有实现具体功能。

    3.1.2 存储规则

    1. 默认存储主目录 video_normal
    2. 主目录下按照日期目录存放 比如 2021-04-07 2021-04-08
    3. 日期目录下是单个的视频文件 比如 Ch1_2021-04-07-14-08-11.mp4。
    4. 拓展功能可以存储对应的数据文件比如经纬度数据和视频文件一个目录 名称一样 拓展名可以是 txt

    3.1.3 视频下载

    视频下载是将查询出来的视频文件,按照勾选了的文件保存到选择的目录中。

    3.2 远程回放

    +远程回放模块是用来通过sdk的形式回放远程NVR设备上的录像文件,这个暂未实现,本系统主要是为了兼容性和通用性,通过具体sdk形式调用的处理都没有做,破坏了移植性,到了其他平台就没法使用了,本系统sdk使用这块默认用的海康sdk作为示例。

    3.3 设备播放

    设备播放模块主要是通过rtsp视频流的形式来拉取实时视频和回放视频,现在越来越多的NVR支持直接通过取流的形式来拉取实时视频流和回放视频,这样使用起来很方便,当然在拉取视频流的时候要传入用户信息,防止非法获取,现在越来越多的应用场景需要通过NVR来调取回放视频,传统的SDK的方式非常累厂家太多,而国标的形式太繁琐复杂,于是rtsp形式的最简单的方式应运而生,目前支持的厂家也越来越多,每个厂家格式的规则不一样,可以自行咨询厂家的规则,本程序默认实现了海康、大华和深广的规则。

    3.4 图片回放

    3.4.1 图片查询

    -选择设备通道和时间范围,单击查询按钮,会将查询到的图片序列按照日期的形式作为一行添加到列表结果中,双击可以自动播放,可以调节播放速度。

    3.4.2 存储规则

    1. 默认存储主目录 image_normal
    2. 主目录下按照日期目录存放 比如 2021-04-07 2021-04-08
    3. 日期目录下是单个的图片文件 比如 Ch1_2021-04-07-14-08-11-222.jpg。
    4. 拓展功能可以存储对应的数据文件比如警情文字和图片文件一个目录 名称一样 拓展名可以是 txt 。

    3.4.3 图片下载

    将勾选的图片序列文件,导出到选择的目录。

    3.4.4 导出报告

    +选择设备通道和时间范围,单击查询按钮,会将查询到的图片序列按照日期的形式作为一行添加到列表结果中,双击可以自动播放,可以调节播放速度。

    3.4.2 存储规则

    1. 默认存储主目录 image_normal
    2. 主目录下按照日期目录存放 比如 2021-04-07 2021-04-08
    3. 日期目录下是单个的图片文件 比如 Ch1_2021-04-07-14-08-11-222.jpg。
    4. 拓展功能可以存储对应的数据文件比如警情文字和图片文件一个目录 名称一样 拓展名可以是 txt 。

    3.4.3 图片下载

    +将勾选的图片序列文件,导出到选择的目录。

    3.4.4 导出报告

    图文混排,可以自定义信息,封装好的类,传入图片队列,图片自适应等比例缩放显示,超过自动分页。

    3.5 视频上传

    视频上传功能主要用来将本地存储的视频文件(也可以是其他文件),通过网络传输(默认TCP)上传到其他地方比如服务器,服务器上要运行接收文件的程序,这样就相当于远程备份视频文件的功能,视频文件可以勾选需要上传哪一些。

    3.5.1 本地设置

    本地只需要在视频监控系统客户端上切换到视频上传页面,然后选择要查询的日期范围,单击查询,会将视频文件查询出来显示在左边的表格中,可以勾选要上传的视频文件,右侧填写好服务器的IP和端口(默认6000),单击上传按钮,会多线程的形式上传文件。

    3.5.2 远程设置

    远程需要放置文件传输工具,该工具完整源码如果购买了视频监控系统,可以赠送,该工具同时具备了发送端和接收端的功能,配套视频监控系统使用的是接收端,视频监控系统作为发送端,填好监听端口后,单击监听按钮,一旦有连接文件上传,会自动显示对应的接收进度,文件名称以上传的文件名为准。

    3.5.3 文件加密

    默认文件传输过程采用了加密机制,意味着传输的数据是加密后的数据,接收到以后根据设置的秘钥进行解密重新生成文件,防止文件传输过程中被拦截,可自定义加密规则。

    3.5.4 功能特点

    1. 多线程收发文件,支持加密传输。
    2. 接收端支持监听端口接收文件和主动连接服务器接收文件两种方式。
    3. 按照 文件开始符+文件大小+文件内容+文件结束符 逐个分包接收。
    4. 可对接收的加密过的文件包进行解密输出。
    5. 如果采用连接服务器方式接收文件可指定请求文件。
    6. 接收端请求文件的形式可以作为通用的程序升级方案。
    7. 进度条实时更新收发文件的进度。
    8. 发送端可设置每个包最很大小即切片分包数量。
    9. 发送端可对文件的每个包进行加密传输。
    10. 发送端支持对包进行合并发送。
    11. 可指定目录对客户端发来的请求文件进行搜索。
    12. 每个功能独立的一个类,接口清晰友好,使用方便。
    13. 支持任意Qt版本、任意系统、任意编译器。

     

    4 电子地图

    电子地图有多个子模块,分别不同的功能,在每个模块上,双击对应的摄像机,都可以弹出实时视频预览画面,支持多个画面同时打开,每个摄像机都一个画面窗体。

    1. 图片地图:摄像机分布在平面图上。
    2. 离线地图:默认采用百度离线瓦片地图,本地使用。
    3. 在线地图:默认采用百度地图,需要联网使用。
    4. 路径规划:指定起始点和终点经纬度坐标,查询最优路径并绘制路线,提取路线坐标集合,动态模拟轨迹,比如机器人和飞机轨迹。

    4.1 双击预览

    4.2 图片地图

    1. 图片地图的功能是为了方便直接提供图片文件,然后摄像机点位可直接拖动,更精确定位的场景,图片可以提供鸟瞰图这种,看起来更直观大气,有3D的感觉。
    2. 图片文件存放在可执行文件下的map文件夹下,如果需要增加或者删除,可以直接文件操作即可,比如复制新的图片文件到这个目录下即可。
    3. 具体摄像机对应哪张图片,可以在摄像机管理中设置,对应字段为地图,直接下拉选择对应的地图即可,默认选择无,就是该摄像机不属于任何地图。

    4.3 离线地图

    功能和在线地图完全一致,唯一区别就是地图是离线的,不需要联网。离线的地图需要自己准备好,可以网上通过瓦片地图下载器来下载需要的地方的离线地图,一般离线地图比较大,他是一张张图片,所以建议离线地图只下载自己需要的即可,比如某个县的地图,而不是所有的,所有的起码有几十GB。

    使用说明 默认系统提供的是上海市的地图,下载地址在下面文章中,会自动更新地址: https://blog.csdn.net/feiyangqingyun/article/details/104005917