feat(对接摄像头信息)

This commit is contained in:
徐超 2024-10-24 17:24:50 +08:00
parent 171b0097f5
commit 3f1ffca856
23 changed files with 1364 additions and 18 deletions

50
.gitignore vendored Normal file
View File

@ -0,0 +1,50 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
*.vcxproj.user
*.zip
Debug
Release
.vs
GeneratedFiles
moc_*.cpp
*.pdb
*.lib
*.exp
*.lib
*.pdb
*.exp
*.output

View File

@ -1,21 +1,265 @@
#include "CameraLoopPlay.h" #include "CameraLoopPlay.h"
#include "ui_CameraLoopPlay.h"
#include "ui_SingleCameraWidget.h"
#include <QTimer>
#include <QDateTime>
#include <qgroupbox>
#include <QStandardItemModel>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
// 相机列表JSON文件名称
const QString CameraJsonFileName = "camera.json";
CameraLoopPlay::CameraLoopPlay(QWidget* parent) CameraLoopPlay::CameraLoopPlay(QWidget* parent)
: QMainWindow(parent), ui(new Ui::CameraLoopPlayClass) : QMainWindow(parent), ui(new Ui::CameraLoopPlayClass)
{ {
ui->setupUi(this); ui->setupUi(this);
// 茶꾜꽉데으 // 隐藏菜单栏
setWindowFlag(Qt::FramelessWindowHint); setWindowFlag(Qt::FramelessWindowHint);
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint); setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint);
qRegisterMetaType<HWND>("HWND");
m_cameraLoopThread = new QThread(this);
m_cameraThread = new CameraThread();
m_cameraThread->moveToThread(m_cameraLoopThread);
connect(m_cameraLoopThread, &QThread::started, m_cameraThread, &CameraThread::run);
connect(m_cameraLoopThread, &QThread::finished, m_cameraThread, &CameraThread::stop);
connect(this, &CameraLoopPlay::loginSignal, m_cameraThread, &CameraThread::login);
connect(this, &CameraLoopPlay::realPlaySignal, m_cameraThread, &CameraThread::realPlay);
connect(this, &CameraLoopPlay::stopReadPlaySignal, m_cameraThread, &CameraThread::stopRealPlay);
m_cameraLoopThread->start();
calendarTimerUpdater();
connect(ui->comboBox_windowNumber, SIGNAL(currentIndexChanged(int)), this, SLOT(changeWindowNumber(int)));
initTreeViewCameraList();
initCameraFarmes();
} }
CameraLoopPlay::~CameraLoopPlay() CameraLoopPlay::~CameraLoopPlay()
{ {
// 关闭并等待视频轮播线程完成
if (m_cameraThread && m_cameraLoopThread->isRunning()) {
m_cameraLoopThread->quit();
m_cameraLoopThread->wait();
}
delete m_cameraLoopThread;
delete m_cameraThread;
delete ui; delete ui;
} }
bool CameraLoopPlay::eventFilter(QObject* watched, QEvent* event)
{
return false;
}
void CameraLoopPlay::on_pushButton_min_clicked()
{
this->showMinimized();
}
void CameraLoopPlay::on_pushButton_slide_clicked()
{
if (m_unfold) {
ui->widget_left->hide();
ui->pushButton_slide->setStyleSheet("border-image: url(:/CameraLoopPlay/Resource/image/unfold.png);");
m_unfold = false;
}
else {
ui->widget_left->show();
ui->pushButton_slide->setStyleSheet("border-image: url(:/CameraLoopPlay/Resource/image/fold.png);");
m_unfold = true;
}
}
void CameraLoopPlay::on_pushButton_loopPlay_clicked()
{
if (ui->pushButton_loopPlay->text() == QStringLiteral("开启轮播")) {
ui->pushButton_loopPlay->setText(QStringLiteral("关闭轮播"));
// 开启轮播
startLoopPlay();
}
else {
ui->pushButton_loopPlay->setText(QStringLiteral("开启轮播"));
// 关闭轮播
stopLoopPlay();
}
}
void CameraLoopPlay::changeWindowNumber(int index)
{
if (index == 0) {
addCameraWidgetToCameraFarmes(1, 1);
}
else if (index == 1) {
addCameraWidgetToCameraFarmes(2, 2);
}
else if (index == 2) {
addCameraWidgetToCameraFarmes(3, 3);
}
else if (index == 3) {
addCameraWidgetToCameraFarmes(4, 4);
}
else if (index == 4) {
addCameraWidgetToCameraFarmes(4, 5);
}
else if (index == 5) {
addCameraWidgetToCameraFarmes(6, 6);
}
}
void CameraLoopPlay::addCameraWidgetToCameraFarmes(int rows, int cols)
{
// 清除已有的布局项
QLayoutItem* item;
while ((item = ui->gridLayout_cameraFarmes->takeAt(0)) != nullptr) {
delete item->widget();
delete item;
}
// 停止摄像头播放
stopVideoStreamPlay();
m_singleCameraWidgetList.clear();
//m_lastFocusSignalCameraWidget = nullptr;
// 遍历行和列添加widget到gridLayout中
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
int index = (row * cols + col);
QWidget* cameraWidgetContainer = new QWidget;
Ui::SingleCameraWidget* signalCameraWidget = new Ui::SingleCameraWidget;
signalCameraWidget->setupUi(cameraWidgetContainer);
signalCameraWidget->label_cameraNumber->hide();
if (m_cameraDeviceInfoList.count() > index) {
signalCameraWidget->widget_camera->setCameraName( m_cameraDeviceInfoList[index].getName());
signalCameraWidget->widget_camera->setCameraWidgetWidth( signalCameraWidget->widget_camera->width());
signalCameraWidget->label_cameraNumber->setText( m_cameraDeviceInfoList[index].getName());
emit realPlaySignal((HWND)signalCameraWidget->label_camera->winId(), index);
signalCameraWidget->label_camera->raise();
}
else {
signalCameraWidget->widget_camera->setCameraName(QStringLiteral("无视频%1").arg(index));
}
signalCameraWidget->label_camera->installEventFilter(this);
signalCameraWidget->label_camera->setFocusPolicy(Qt::StrongFocus);
m_singleCameraWidgetList.append(signalCameraWidget);
ui->gridLayout_cameraFarmes->addWidget(cameraWidgetContainer, row, col);
}
}
}
void CameraLoopPlay::calendarTimerUpdater()
{
QTimer* timer_calendar = new QTimer(this);
connect(timer_calendar, &QTimer::timeout, this, [this]() {
QDateTime time = QDateTime::currentDateTime();
QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");
ui->label_clander->setText(str);
});
timer_calendar->start(1000); //每一秒溢出一次进入槽函数
}
void CameraLoopPlay::startLoopPlay()
{
}
void CameraLoopPlay::stopLoopPlay()
{
}
void CameraLoopPlay::initTreeViewCameraList()
{
ui->treeView_cameraList->setHeaderHidden(true);
ui->treeView_cameraList->setEditTriggers(QAbstractItemView::NoEditTriggers);
readCameraJsonInfo();
}
void CameraLoopPlay::readCameraJsonInfo()
{
QFile file(QCoreApplication::applicationDirPath() + "/" + CameraJsonFileName);
if (file.open(QIODevice::ReadOnly)) {
QByteArray jsonData = file.readAll();
file.close();
int indexValue = 0;
QStandardItemModel* standardItemModel = new QStandardItemModel(this);
QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonData));
QJsonObject jsonObject = jsonDoc.object();
for (auto it = jsonObject.constBegin(); it != jsonObject.constEnd(); ++it) {
QJsonArray jsonArray = it.value().toArray();
QStandardItem* rootItem = new QStandardItem(it.key());
rootItem->setIcon(QIcon(":/CameraLoopPlay/Resource/image/camera.png"));
for (QJsonValue deviceInfo : jsonArray) {
QString cameraDeviceName = deviceInfo["Name"].toString(); // 摄像头名称
QString cameraDeviceIP = deviceInfo["IP"].toString();
QString cameraDeviceUserName = deviceInfo["UserName"].toString();
QString cameraDevicePassWord = deviceInfo["PassWord"].toString();
CameraDeviceInfo cameraDeviceInfo(indexValue, cameraDeviceName, cameraDeviceIP, cameraDeviceUserName, cameraDevicePassWord);
// 登录摄像头
emit loginSignal(cameraDeviceIP, cameraDeviceUserName, cameraDevicePassWord, indexValue, cameraDeviceName);
indexValue++;
// 加入至摄像头列表树
QStandardItem* subItem = new QStandardItem(cameraDeviceName);
subItem->setIcon(QIcon(":/CameraLoopPlay/Resource/image/offline.png"));
rootItem->appendRow(subItem);
m_treeCameraItemList.append(subItem);
m_cameraDeviceInfoList.append(cameraDeviceInfo);
}
standardItemModel->appendRow(rootItem);
}
ui->treeView_cameraList->setModel(standardItemModel);
ui->treeView_cameraList->expandAll();
}
}
void CameraLoopPlay::initCameraFarmes()
{
ui->comboBox_windowNumber->setCurrentIndex(4);
//addCameraWidgetToCameraFarmes(4, 5);
}
void CameraLoopPlay::stopVideoStreamPlay()
{
if (m_cameraDeviceInfoList.isEmpty())
return;
for (int i = 0; i < m_cameraDeviceInfoList.size(); i++) {
int cameraIndex = m_cameraDeviceInfoList.at(i).getTreeindex();
emit stopReadPlaySignal(cameraIndex-1);
}
}
void CameraLoopPlay::on_pushButton_close_clicked() void CameraLoopPlay::on_pushButton_close_clicked()
{ {
this->close(); this->close();

View File

@ -7,7 +7,18 @@
#pragma once #pragma once
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
#include "ui_CameraLoopPlay.h" #include <QThread>
#include <QStandardItem>
#include "model/CameraDeviceInfo.h"
#include "CameraThread.h"
#include "SingleCameraWidget.h"
namespace Ui
{
class CameraLoopPlayClass;
class SingleCameraWidget;
}
class CameraLoopPlay : public QMainWindow class CameraLoopPlay : public QMainWindow
{ {
@ -17,6 +28,38 @@ public:
CameraLoopPlay(QWidget *parent = nullptr); CameraLoopPlay(QWidget *parent = nullptr);
~CameraLoopPlay(); ~CameraLoopPlay();
protected:
bool eventFilter(QObject* watched, QEvent* event) override;
signals:
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void realPlaySignal(HWND hWnd, int hWndIndex);
/**
* @brief .
* @param strIP IP
* @param strUser
* @param strPwd
* @param hWndIndex
* @param cameraName
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void loginSignal(QString strIP, QString strUser, QString strPwd, int hWndIndex, QString cameraName);
/**
* @brief .
* @param hwndIndex
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void stopReadPlaySignal(int hwndIndex);
private slots: private slots:
/** /**
@ -26,6 +69,142 @@ private slots:
*/ */
void on_pushButton_close_clicked(); void on_pushButton_close_clicked();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void on_pushButton_min_clicked();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void on_pushButton_slide_clicked();
/**
* @brief /.
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void on_pushButton_loopPlay_clicked();
/**
* @brief .
* @param index
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void changeWindowNumber(int index);
private:
/**
* @brief .
* @param rows
* @param cols
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void addCameraWidgetToCameraFarmes(int rows, int cols);
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void calendarTimerUpdater();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void startLoopPlay();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void stopLoopPlay();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void initTreeViewCameraList();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void readCameraJsonInfo();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void initCameraFarmes();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void stopVideoStreamPlay();
private: private:
Ui::CameraLoopPlayClass *ui = nullptr; Ui::CameraLoopPlayClass *ui = nullptr;
/**
* @brief 线
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
QThread* m_cameraLoopThread{ nullptr };
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
CameraThread* m_cameraThread{ nullptr };
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
bool m_unfold = true;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
QList<CameraDeviceInfo> m_cameraDeviceInfoList;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
QList<QStandardItem*> m_treeCameraItemList;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
QList<Ui::SingleCameraWidget*> m_singleCameraWidgetList;
}; };

View File

@ -26,5 +26,9 @@
<file>Resource/image/zoom.png</file> <file>Resource/image/zoom.png</file>
<file>Resource/image/close.png</file> <file>Resource/image/close.png</file>
<file>Resource/image/close_hover.png</file> <file>Resource/image/close_hover.png</file>
<file>Resource/image/head_title.png</file>
<file>Resource/image/AI摄像头.ico</file>
<file>Resource/image/min.png</file>
<file>Resource/image/min_honver.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -36,19 +36,28 @@
<widget class="QWidget" name="widget_title" native="true"> <widget class="QWidget" name="widget_title" native="true">
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">#widget_title{ <string notr="true">#widget_title{
border-image: url(:/CameraLoopPlay/Resource/image/yuquan_workface_title.png); border-image: url(:/CameraLoopPlay/Resource/image/head_title.png);
background-color: transparent; background-color: transparent;
}</string> }</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>20</number>
</property>
<property name="bottomMargin">
<number>30</number>
</property>
<item> <item>
<spacer name="horizontalSpacer_3"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>750</width>
<height>20</height> <height>20</height>
</size> </size>
</property> </property>
@ -56,14 +65,23 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="label_title"> <widget class="QLabel" name="label_title">
<property name="font">
<font>
<family>黑体</family>
<pointsize>28</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">#label_title{ <string notr="true">#label_title{
color:white; color:white;
font: 24pt &quot;黑体&quot;; font: 28pt &quot;黑体&quot;;
}</string> }</string>
</property> </property>
<property name="text"> <property name="text">
<string>标题示例</string> <string>玉泉煤业工作面视频监控</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -95,6 +113,29 @@ font: 16pt &quot;Arial&quot;;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButton_min">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border-image: url(:/CameraLoopPlay/Resource/image/min.png);
border:0;
}
QPushButton:hover{
border-image: url(:/CameraLoopPlay/Resource/image/min_honver.png);
border:0;
}</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="pushButton_close"> <widget class="QPushButton" name="pushButton_close">
<property name="minimumSize"> <property name="minimumSize">
@ -263,6 +304,46 @@ QPushButton:hover{
background-color: transparent; background-color: transparent;
font-size:18px; font-size:18px;
color:white; color:white;
}
QScrollBar:vertical{
width:8px;
background:rgba(80,180,255,100%);
margin:0px,0px,0px,0px;
padding-top:2px;
padding-bottom:2px;
border-radius:4px;
}
QScrollBar::handle:vertical
{
width:8px;
background:rgba(0,0,0,25%);
border-radius:4px;
min-height:20;
}
QScrollBar::handle:vertical:hover
{
width:8px;
background:rgba(0,0,0,50%);
border-radius:4px;
min-height:20;
}
QScrollBar::add-line:vertical
{
height:9px;width:8px;
background-color:transparent;
subcontrol-position:bottom;
}
QScrollBar::sub-line:vertical
{
height:9px;width:8px;
background-color:transparent;
subcontrol-position:top;
}
QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical
{
background:rgba(0,0,0,10%);
border-radius:4px;
}</string> }</string>
</property> </property>
</widget> </widget>

View File

@ -1,8 +1,195 @@
#include "CameraThread.h" #include "CameraThread.h"
#include <qdebug.h>
#include <QTimer>
CameraThread::CameraThread(QObject *parent) CameraThread::CameraThread(QObject *parent)
: QObject(parent) : QObject(parent)
{} {
checkLoginState();
checkLoginStatu();
}
CameraThread::~CameraThread() CameraThread::~CameraThread()
{} {}
void CameraThread::run()
{
initSDK();
}
void CameraThread::stop()
{
cleanupSDK();
}
void CameraThread::login(QString strIP, QString strUser, QString strPwd, int hWndIndex, QString cameraName)
{
CameraDeviceInfo cameraDeviceInfo(hWndIndex,cameraName, strIP, strUser, strPwd);
HWNDloginMsg.insert(hWndIndex, cameraDeviceInfo);
if (HWNDlogin.contains(hWndIndex) && HWNDlogin[cameraDeviceInfo.getIndex()] >= 0) {
logout(HWNDlogin[hWndIndex]);
}
int loginId = -1;
long iRealPlayHandle = -1;
NET_DVR_USER_LOGIN_INFO struLoginInfo = {}; // 异步登录的状态、用户 ID 和设备信息通过 NET_DVR_USER_LOGIN_INFO 结构体中设置的回调函数 (fLoginResultCallBack)返回。
NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {};
struLoginInfo.bUseAsynLogin = false; //同步登录方式
struLoginInfo.wPort = 8000; //设备服务端口
strcpy_s(struLoginInfo.sDeviceAddress, strIP.toLatin1().data()); //设备ip地址
strcpy_s(struLoginInfo.sUserName, strUser.toLatin1().data()); //设备登录用户名
strcpy_s(struLoginInfo.sPassword, strPwd.toLatin1().data()); //设备登录密码
//设备信息, 输出参数
loginId = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40); // 用户注册设备
qDebug() << "loginId" << loginId;
HWNDlogin.insert(hWndIndex, loginId);
iIpcStartChan.insert(hWndIndex, struDeviceInfoV40.struDeviceV30.byStartChan);
}
bool CameraThread::realPlay(HWND hWnd, int index)
{
int loginId = HWNDlogin[index];
if (loginId == -1) {
return false;
}
if (HWNDPlayHandle.contains(index) && HWNDPlayHandle[index] >= 0)
return true;
long iRealPlayHandle = -1;
NET_DVR_PREVIEWINFO struPlayInfo = {};
struPlayInfo = {};
struPlayInfo.hPlayWnd = hWnd; //需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
struPlayInfo.lChannel = 0 + iIpcStartChan[index]; //预览通道号
struPlayInfo.dwStreamType = 1; //码流类型0-主码流1-子码流2-三码流3-虚拟码流,以此类推
struPlayInfo.dwLinkMode = 4; //0- TCP 方式1- UDP 方式2- 多播方式3- RTP 方式4-RTP/RTSP5-RSTP/HTTP
struPlayInfo.bBlocked = 1; //0- 非阻塞取流1- 阻塞取流
iRealPlayHandle = NET_DVR_RealPlay_V40(loginId, &struPlayInfo, NULL, NULL); // 实时预览
IsPlay.insert(index, 5);
if (iRealPlayHandle < 0) {
qDebug() << "NET_DVR_RealPlay_V40 error;error number " << NET_DVR_GetLastError();
return -1;
}
IndexHWNDMap.insert(index, hWnd);
HWNDPlayHandle.insert(index, iRealPlayHandle);
return iRealPlayHandle;
}
int CameraThread::stopRealPlay(int hWndIndex)
{
int iRealPlayHandle = HWNDPlayHandle[hWndIndex];
int errorId = 0;
if (iRealPlayHandle == -1) {
return true;
}
if (!NET_DVR_StopRealPlay(iRealPlayHandle)) {
errorId = NET_DVR_GetLastError();
}
if (IsPlay.contains(hWndIndex)) {
IsPlay.remove(hWndIndex);
}
HWNDPlayHandle[hWndIndex] = -1;
return errorId;
}
bool CameraThread::initSDK()
{
// 初始化
bool isok = NET_DVR_Init();
if (isok == false) {
qDebug() << "NET_DVR_Init error;error number is " << NET_DVR_GetLastError(); // 返回最后操作的错误码
return isok;
}
//设置连接时间与重连时间
NET_DVR_SetConnectTime(2000, 1); // 设置网络连接超时时间和连接尝试次数
NET_DVR_SetReconnect(10000, true); // 设置重连功能
return isok;
}
bool CameraThread::cleanupSDK()
{
// 释放 SDK 资源
bool isok = NET_DVR_Cleanup();
if (isok == false) {
qDebug() << "NET_DVR_Cleanup error;error number is " << NET_DVR_GetLastError();
return isok;
}
return isok;
}
void CameraThread::checkLoginState()
{
// 每秒检查并执行 IsPlay 列表中的播放任务
QTimer* replayTime = new QTimer(this);
connect(replayTime, &QTimer::timeout, this, [=]() {
if (IsPlay.count() > 0) {
QList<int> tmp;
for (int i = 0; i < IsPlay.count(); i++) {
// realPlay() 进行播放
realPlay(IndexHWNDMap[IsPlay.keys()[i]], IsPlay.keys()[i]);
IsPlay[IsPlay.keys()[i]]--;
if (IsPlay[IsPlay.keys()[i]] == 0) {
tmp.append(IsPlay.keys()[i]);
}
}
for (int i = 0; i < tmp.count(); i++) {
IsPlay.remove(tmp[i]);
}
}
});
replayTime->start(1000);
}
int CameraThread::logout(int loginId)
{
int errorId = 0;
if (loginId == -1 || loginId < 0) {
return true;
}
if (!NET_DVR_Logout(loginId)) {
errorId = NET_DVR_GetLastError();
}
return errorId;
}
void CameraThread::checkLoginStatu()
{
// 每隔10 分钟定时检查登录状态
QTimer* checkOnline = new QTimer(this);
connect(checkOnline, &QTimer::timeout, this, [=]() {
if (HWNDlogin.count() > 0) {
for (int i = 0; i < HWNDlogin.count(); i++) {
int loginIndex = HWNDlogin.keys()[i];
int loginId = HWNDlogin[loginIndex];
if (loginId == -1) {
login(HWNDloginMsg[loginIndex].getIp(), HWNDloginMsg[loginIndex].getUsername(), HWNDloginMsg[loginIndex].getPassword(), loginIndex,HWNDloginMsg[loginIndex].getName());
}
else {
bool isonline = NET_DVR_RemoteControl(loginId, 20005, nullptr, 0);
if (!isonline) {
login(HWNDloginMsg[loginIndex].getIp(), HWNDloginMsg[loginIndex].getUsername(), HWNDloginMsg[loginIndex].getPassword(), loginIndex, HWNDloginMsg[loginIndex].getName());
}
}
}
}
});
checkOnline->start(600000);
}

View File

@ -1,18 +1,153 @@
/*****************************************************************//**
* @file CameraThread.h
* @brief 线
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*********************************************************************/
#pragma once #pragma once
#include <QObject> #include <QObject>
#include <qmap.h>
#include "windows.h"
#include "HCNetSDK.h" #include "HCNetSDK.h"
#include "cameradeviceinfo.h"
class CameraThread : public QObject class CameraThread : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
CameraThread(QObject *parent); CameraThread(QObject *parent = nullptr);
~CameraThread(); ~CameraThread();
signals:
void loginResultSignal(long loginId, int iRealPlayHandle, int hWndIndex);
public slots:
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void run();
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void stop();
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
void login(QString strIP, QString strUser, QString strPwd, int loginIndex, QString cameraName);
/**
* @brief .
* @param hWnd
* @param index
* @return
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
bool realPlay(HWND hWnd, int index);
/**
* @brief .
* @param hWndIndex
* @return
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
int stopRealPlay(int hWndIndex);
private:
/**
* @brief sdk资源.
* @return true false
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
bool initSDK();
/**
* @brief sdk资源.
* @return
* @author XuChao (xxu715737@163.com)
* @date 2024-10-23
*/
bool cleanupSDK();
/**
* @brief IsPlay列表中的播放任务.
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void checkLoginState();
/**
* @brief 退.
* @param loginId
* @return
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
int logout(int loginId);
/**
* @brief .
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
void checkLoginStatu();
private:
/**
* @brief ,
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, CameraDeviceInfo> HWNDloginMsg;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, int> iIpcStartChan;
/**
* @brief ID映射
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, int> HWNDlogin;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, int> HWNDPlayHandle;
/**
* @brief key
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, int> IsPlay;
/**
* @brief
* @author XuChao (xxu715737@163.com)
* @date 2024-10-24
*/
QMap<int, HWND> IndexHWNDMap;
}; };

View File

@ -0,0 +1,10 @@
#include "ControlptzWidget.h"
ControlptzWidget::ControlptzWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
ControlptzWidget::~ControlptzWidget()
{}

View File

@ -0,0 +1,16 @@
#pragma once
#include <QWidget>
#include "ui_ControlptzWidget.h"
class ControlptzWidget : public QWidget
{
Q_OBJECT
public:
ControlptzWidget(QWidget *parent = nullptr);
~ControlptzWidget();
private:
Ui::ControlptzWidgetClass ui;
};

View File

@ -0,0 +1,22 @@
<UI version="4.0" >
<class>ControlptzWidgetClass</class>
<widget class="QWidget" name="ControlptzWidgetClass" >
<property name="objectName" >
<string notr="true">ControlptzWidgetClass</string>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle" >
<string>ControlptzWidget</string>
</property>$centralwidget$
</widget>
<layoutDefault spacing="6" margin="11" />
<pixmapfunction></pixmapfunction>
<connections/>
</UI>

View File

@ -66,6 +66,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\external\CH-HCNetSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\external\CH-HCNetSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalLibraryDirectories>..\external\CH-HCNetSDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\external\CH-HCNetSDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -95,22 +96,34 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="component\videowindowscomponent.cpp" />
<ClCompile Include="ControlptzWidget.cpp" />
<ClCompile Include="SingleCameraWidget.cpp" />
<QtRcc Include="CameraLoopPlay.qrc" /> <QtRcc Include="CameraLoopPlay.qrc" />
<QtUic Include="CameraLoopPlay.ui" /> <QtUic Include="CameraLoopPlay.ui" />
<QtMoc Include="CameraLoopPlay.h" /> <QtMoc Include="CameraLoopPlay.h" />
<ClCompile Include="CameraLoopPlay.cpp" /> <ClCompile Include="CameraLoopPlay.cpp" />
<ClCompile Include="CameraThread.cpp" /> <ClCompile Include="CameraThread.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<QtUic Include="ControlptzWidget.ui" />
<QtUic Include="SingleCameraWidget.ui" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="CameraThread.h" /> <QtMoc Include="CameraThread.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="cameradeviceinfo.h" />
<ClInclude Include="model\CameraDeviceInfo.h" />
<QtMoc Include="component\videowindowscomponent.h" />
<QtMoc Include="ControlptzWidget.h" />
<QtMoc Include="SingleCameraWidget.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')"> <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" /> <Import Project="$(QtMsBuild)\qt.targets" />

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="Header Files\component">
<UniqueIdentifier>{08feb7d5-209b-4a70-8be8-2943dbd43e49}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\component">
<UniqueIdentifier>{36367f84-7f0a-45d9-8b96-53eaa0db232d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="CameraLoopPlay.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<QtUic Include="CameraLoopPlay.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtMoc Include="CameraLoopPlay.h">
<Filter>Header Files</Filter>
</QtMoc>
<ClCompile Include="CameraLoopPlay.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CameraThread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SingleCameraWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ControlptzWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="component\videowindowscomponent.cpp">
<Filter>Source Files\component</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="CameraThread.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="SingleCameraWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="ControlptzWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="component\videowindowscomponent.h">
<Filter>Header Files\component</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cameradeviceinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="model\CameraDeviceInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtUic Include="SingleCameraWidget.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="ControlptzWidget.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

View File

@ -0,0 +1,12 @@
#include "SingleCameraWidget.h"
SingleCameraWidget::SingleCameraWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
SingleCameraWidget::~SingleCameraWidget()
{
}

View File

@ -0,0 +1,16 @@
#pragma once
#include <QWidget>
#include "ui_SingleCameraWidget.h"
class SingleCameraWidget : public QWidget
{
Q_OBJECT
public:
SingleCameraWidget(QWidget *parent = nullptr);
~SingleCameraWidget();
private:
Ui::SingleCameraWidget ui;
};

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SingleCameraWidget</class>
<widget class="QWidget" name="SingleCameraWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>585</width>
<height>393</height>
</rect>
</property>
<property name="windowTitle">
<string>SingleCameraWidget</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="VideoWindowsComponent" name="widget_camera" native="true">
<property name="styleSheet">
<string notr="true">#widget_camera{
border-image: url(:/CameraLoopPlay/Resource/image/rect.png);
}
</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="label_cameraNumber">
<property name="styleSheet">
<string notr="true">color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_camera">
<property name="styleSheet">
<string notr="true">QLabel{
font:75 25px;
color:#F0F0F0;
border:2px solid #AAAAAA;
background:transparent;
}
QLabel:focus{
border:2px solid #00BB9E;
background:transparent;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>VideoWindowsComponent</class>
<extends>QWidget</extends>
<header>component/videowindowscomponent.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,46 @@
#ifndef CAMERADEVICEINFO_H
#define CAMERADEVICEINFO_H
#include <QString>
class CameraDeviceInfo {
public:
// 构造函数
CameraDeviceInfo(const int& index = 0,
const QString& name = "",
const QString& ip = "",
const QString& username = "",
const QString& password = "")
: index(index)
, name(name)
, ip(ip)
, username(username)
, password(password)
{
}
int getIndex() const { return index; }
void setIndex(const int& newIndex) { index = newIndex; }
// Getters 和 Setters
QString getName() const { return name; }
void setName(const QString& newName) { name = newName; }
QString getIp() const { return ip; }
void setIp(const QString& newIp) { ip = newIp; }
QString getUsername() const { return username; }
void setUsername(const QString& newUsername) { username = newUsername; }
QString getPassword() const { return password; }
void setPassword(const QString& newPassword) { password = newPassword; }
private:
// 设备信息
int index{ 0 }; // 索引值
QString name { "" }; // 设备名称
QString ip { "" }; // 设备IP地址
QString username { "" }; // 设备用户名
QString password { "" }; // 设备密码
};
#endif // CAMERADEVICEINFO_H

View File

@ -0,0 +1,40 @@
#include "videowindowscomponent.h"
#include "QHBoxLayout"
#include "QtDebug"
VideoWindowsComponent::VideoWindowsComponent(QWidget* parent)
: QWidget(parent)
{
standNumberWidget = new QLabel(m_cameraName, this);
standNumberWidget->setStyleSheet("background-color: rgba(173, 216, 230, 150); padding: 2px; color: white;");
standNumberWidget->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
// 设置 QLabel 默认位置和大小
standNumberWidget->move(7, 7); // 设置支架号 label 的初始位置(比如视频窗口左上角)
standNumberWidget->hide(); // 默认隐藏
}
void VideoWindowsComponent::setCameraName(const QString& cameraName)
{
m_cameraName = cameraName;
}
void VideoWindowsComponent::setCameraWidgetWidth(const double& cameraWidgetWidth)
{
m_cameraWidgetWidget = cameraWidgetWidth;
}
void VideoWindowsComponent::enterEvent(QEvent* event)
{
standNumberWidget->show();
standNumberWidget->setText(m_cameraName);
// standNumberWidget->setFixedSize(this->width() - 20, 25); // 设置固定的大小
standNumberWidget->resize(this->width() - 14, 25);
standNumberWidget->raise();
QWidget::enterEvent(event); // 调用基类的enterEvent方法
}
void VideoWindowsComponent::leaveEvent(QEvent* event)
{
standNumberWidget->hide();
QWidget::leaveEvent(event); // 调用基类的leaveEvent方法
}

View File

@ -0,0 +1,29 @@
#ifndef VIDEOWINDOWSCOMPONENT_H
#define VIDEOWINDOWSCOMPONENT_H
#include <QEvent>
#include <QLabel>
#include <QObject>
#include <QWidget>
class VideoWindowsComponent : public QWidget {
Q_OBJECT
public:
VideoWindowsComponent(QWidget* parent = nullptr);
void setCameraName(const QString& cameraName);
void setCameraWidgetWidth(const double& cameraWidgetWidth);
protected:
void enterEvent(QEvent* event) override;
void leaveEvent(QEvent* event) override;
private:
QLabel* standNumberWidget;
QString m_cameraName;
double m_cameraWidgetWidget;
};
#endif // VIDEOWINDOWSCOMPONENT_H

View File

@ -0,0 +1,46 @@
#ifndef CAMERADEVICEINFO_H
#define CAMERADEVICEINFO_H
#include <QString>
class CameraDeviceInfo {
public:
// 构造函数
CameraDeviceInfo(const int& treeIndex = 0,
const QString& name = "",
const QString& ip = "",
const QString& username = "",
const QString& password = "")
: treeindex(treeIndex)
, name(name)
, ip(ip)
, username(username)
, password(password)
{
}
int getTreeindex() const { return treeindex; }
void setTreeIndex(const int& newTreeIndex) { treeindex = newTreeIndex; }
// Getters 和 Setters
QString getName() const { return name; }
void setName(const QString& newName) { name = newName; }
QString getIp() const { return ip; }
void setIp(const QString& newIp) { ip = newIp; }
QString getUsername() const { return username; }
void setUsername(const QString& newUsername) { username = newUsername; }
QString getPassword() const { return password; }
void setPassword(const QString& newPassword) { password = newPassword; }
private:
// 设备信息
int treeindex{ 0 }; // 索引值
QString name{ "" }; // 设备名称
QString ip{ "" }; // 设备IP地址
QString username{ "" }; // 设备用户名
QString password{ "" }; // 设备密码
};
#endif // CAMERADEVICEINFO_H