diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d856f20 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/HX_CameraLoopPlay/CameraLoopPlay.cpp b/HX_CameraLoopPlay/CameraLoopPlay.cpp index 2c9a69f..f6aeb28 100644 --- a/HX_CameraLoopPlay/CameraLoopPlay.cpp +++ b/HX_CameraLoopPlay/CameraLoopPlay.cpp @@ -1,24 +1,268 @@ -#include "CameraLoopPlay.h" +#include "CameraLoopPlay.h" +#include "ui_CameraLoopPlay.h" +#include "ui_SingleCameraWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include -CameraLoopPlay::CameraLoopPlay(QWidget *parent) - : QMainWindow(parent), ui(new Ui::CameraLoopPlayClass) +// 相机列表JSON文件名称 +const QString CameraJsonFileName = "camera.json"; + +CameraLoopPlay::CameraLoopPlay(QWidget* parent) + : QMainWindow(parent), ui(new Ui::CameraLoopPlayClass) { - ui->setupUi(this); + ui->setupUi(this); - // ز˵ - setWindowFlag(Qt::FramelessWindowHint); - setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint); + // 隐藏菜单栏 + setWindowFlag(Qt::FramelessWindowHint); + setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint); + + qRegisterMetaType("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() { - delete ui; + // 关闭并等待视频轮播线程完成 + if (m_cameraThread && m_cameraLoopThread->isRunning()) { + m_cameraLoopThread->quit(); + m_cameraLoopThread->wait(); + } + + delete m_cameraLoopThread; + delete m_cameraThread; + 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() { - this->close(); + this->close(); } diff --git a/HX_CameraLoopPlay/CameraLoopPlay.h b/HX_CameraLoopPlay/CameraLoopPlay.h index fe3433a..0ef84b0 100644 --- a/HX_CameraLoopPlay/CameraLoopPlay.h +++ b/HX_CameraLoopPlay/CameraLoopPlay.h @@ -7,7 +7,18 @@ #pragma once #include -#include "ui_CameraLoopPlay.h" +#include +#include + +#include "model/CameraDeviceInfo.h" +#include "CameraThread.h" +#include "SingleCameraWidget.h" + +namespace Ui +{ + class CameraLoopPlayClass; + class SingleCameraWidget; +} class CameraLoopPlay : public QMainWindow { @@ -17,6 +28,38 @@ public: CameraLoopPlay(QWidget *parent = nullptr); ~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: /** @@ -26,6 +69,142 @@ private slots: */ 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 ֹͣƵIJ. + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + void stopVideoStreamPlay(); + + private: 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 m_cameraDeviceInfoList; + + /** + * @brief бͷ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-23 + */ + QList m_treeCameraItemList; + + /** + * @brief б + * @author XuChao (xxu715737@163.com) + * @date 2024-10-23 + */ + QList m_singleCameraWidgetList; + + + }; diff --git a/HX_CameraLoopPlay/CameraLoopPlay.qrc b/HX_CameraLoopPlay/CameraLoopPlay.qrc index 4e39902..dbd2a1e 100644 --- a/HX_CameraLoopPlay/CameraLoopPlay.qrc +++ b/HX_CameraLoopPlay/CameraLoopPlay.qrc @@ -26,5 +26,9 @@ Resource/image/zoom.png Resource/image/close.png Resource/image/close_hover.png + Resource/image/head_title.png + Resource/image/AI摄像头.ico + Resource/image/min.png + Resource/image/min_honver.png diff --git a/HX_CameraLoopPlay/CameraLoopPlay.ui b/HX_CameraLoopPlay/CameraLoopPlay.ui index 20fd13a..ad9881a 100644 --- a/HX_CameraLoopPlay/CameraLoopPlay.ui +++ b/HX_CameraLoopPlay/CameraLoopPlay.ui @@ -36,19 +36,28 @@ #widget_title{ - border-image: url(:/CameraLoopPlay/Resource/image/yuquan_workface_title.png); + border-image: url(:/CameraLoopPlay/Resource/image/head_title.png); background-color: transparent; } + + 20 + + + 30 + Qt::Horizontal + + QSizePolicy::Maximum + - 40 + 750 20 @@ -56,14 +65,23 @@ + + + 黑体 + 28 + 50 + false + false + + #label_title{ color:white; - font: 24pt "黑体"; + font: 28pt "黑体"; } - 标题示例 + 玉泉煤业工作面视频监控 @@ -95,6 +113,29 @@ font: 16pt "Arial"; + + + + + 32 + 32 + + + + QPushButton{ + border-image: url(:/CameraLoopPlay/Resource/image/min.png); + border:0; +} +QPushButton:hover{ + border-image: url(:/CameraLoopPlay/Resource/image/min_honver.png); + border:0; +} + + + + + + @@ -263,7 +304,47 @@ QPushButton:hover{ background-color: transparent; font-size:18px; 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; + } diff --git a/HX_CameraLoopPlay/CameraThread.cpp b/HX_CameraLoopPlay/CameraThread.cpp index 9a45f48..bc76b18 100644 --- a/HX_CameraLoopPlay/CameraThread.cpp +++ b/HX_CameraLoopPlay/CameraThread.cpp @@ -1,8 +1,195 @@ #include "CameraThread.h" +#include +#include + CameraThread::CameraThread(QObject *parent) : QObject(parent) -{} +{ + checkLoginState(); + checkLoginStatu(); +} 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 беIJ + QTimer* replayTime = new QTimer(this); + connect(replayTime, &QTimer::timeout, this, [=]() { + if (IsPlay.count() > 0) { + QList 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); +} diff --git a/HX_CameraLoopPlay/CameraThread.h b/HX_CameraLoopPlay/CameraThread.h index e3ab67d..9fd7f44 100644 --- a/HX_CameraLoopPlay/CameraThread.h +++ b/HX_CameraLoopPlay/CameraThread.h @@ -1,18 +1,153 @@ +/*****************************************************************//** + * @file CameraThread.h + * @brief ͷƵֲ߳ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-23 + *********************************************************************/ #pragma once #include +#include +#include "windows.h" #include "HCNetSDK.h" +#include "cameradeviceinfo.h" class CameraThread : public QObject { Q_OBJECT public: - CameraThread(QObject *parent); + CameraThread(QObject *parent = nullptr); ~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беIJ. + * @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 HWNDloginMsg; + + /** + * @brief 豸ʼͨӳ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + QMap iIpcStartChan; + + /** + * @brief 豸¼IDӳ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + QMap HWNDlogin; + + /** + * @brief 豸ʵʱԤ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + QMap HWNDPlayHandle; + + /** + * @brief ¼״̬ keyŴ + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + QMap IsPlay; + + /** + * @brief žź + * @author XuChao (xxu715737@163.com) + * @date 2024-10-24 + */ + QMap IndexHWNDMap; }; diff --git a/HX_CameraLoopPlay/ControlptzWidget.cpp b/HX_CameraLoopPlay/ControlptzWidget.cpp new file mode 100644 index 0000000..a796db3 --- /dev/null +++ b/HX_CameraLoopPlay/ControlptzWidget.cpp @@ -0,0 +1,10 @@ +#include "ControlptzWidget.h" + +ControlptzWidget::ControlptzWidget(QWidget *parent) + : QWidget(parent) +{ + ui.setupUi(this); +} + +ControlptzWidget::~ControlptzWidget() +{} diff --git a/HX_CameraLoopPlay/ControlptzWidget.h b/HX_CameraLoopPlay/ControlptzWidget.h new file mode 100644 index 0000000..11c7749 --- /dev/null +++ b/HX_CameraLoopPlay/ControlptzWidget.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "ui_ControlptzWidget.h" + +class ControlptzWidget : public QWidget +{ + Q_OBJECT + +public: + ControlptzWidget(QWidget *parent = nullptr); + ~ControlptzWidget(); + +private: + Ui::ControlptzWidgetClass ui; +}; diff --git a/HX_CameraLoopPlay/ControlptzWidget.ui b/HX_CameraLoopPlay/ControlptzWidget.ui new file mode 100644 index 0000000..5177eee --- /dev/null +++ b/HX_CameraLoopPlay/ControlptzWidget.ui @@ -0,0 +1,22 @@ + + ControlptzWidgetClass + + + ControlptzWidgetClass + + + + 0 + 0 + 600 + 400 + + + + ControlptzWidget + $centralwidget$ + + + + + diff --git a/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj b/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj index 0bde147..8f85736 100644 --- a/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj +++ b/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj @@ -66,6 +66,7 @@ ..\external\CH-HCNetSDK\include;%(AdditionalIncludeDirectories) + Disabled ..\external\CH-HCNetSDK\lib;%(AdditionalLibraryDirectories) @@ -95,22 +96,34 @@ Windows - false + true true true + + + + + + + + + + + + diff --git a/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj.filters b/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj.filters new file mode 100644 index 0000000..a182a20 --- /dev/null +++ b/HX_CameraLoopPlay/HX_CameraLoopPlay.vcxproj.filters @@ -0,0 +1,92 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} + ts + + + {08feb7d5-209b-4a70-8be8-2943dbd43e49} + + + {36367f84-7f0a-45d9-8b96-53eaa0db232d} + + + + + Resource Files + + + Form Files + + + Header Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\component + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files\component + + + + + Header Files + + + Header Files + + + + + Form Files + + + Form Files + + + \ No newline at end of file diff --git a/HX_CameraLoopPlay/Resource/image/AI摄像头.ico b/HX_CameraLoopPlay/Resource/image/AI摄像头.ico new file mode 100644 index 0000000..72d5666 Binary files /dev/null and b/HX_CameraLoopPlay/Resource/image/AI摄像头.ico differ diff --git a/HX_CameraLoopPlay/Resource/image/head_title.png b/HX_CameraLoopPlay/Resource/image/head_title.png new file mode 100644 index 0000000..d5b1053 Binary files /dev/null and b/HX_CameraLoopPlay/Resource/image/head_title.png differ diff --git a/HX_CameraLoopPlay/Resource/image/min.png b/HX_CameraLoopPlay/Resource/image/min.png new file mode 100644 index 0000000..c962d21 Binary files /dev/null and b/HX_CameraLoopPlay/Resource/image/min.png differ diff --git a/HX_CameraLoopPlay/Resource/image/min_honver.png b/HX_CameraLoopPlay/Resource/image/min_honver.png new file mode 100644 index 0000000..dc2ac4c Binary files /dev/null and b/HX_CameraLoopPlay/Resource/image/min_honver.png differ diff --git a/HX_CameraLoopPlay/SingleCameraWidget.cpp b/HX_CameraLoopPlay/SingleCameraWidget.cpp new file mode 100644 index 0000000..a1fb36d --- /dev/null +++ b/HX_CameraLoopPlay/SingleCameraWidget.cpp @@ -0,0 +1,12 @@ +#include "SingleCameraWidget.h" + +SingleCameraWidget::SingleCameraWidget(QWidget *parent) + : QWidget(parent) +{ + ui.setupUi(this); +} + +SingleCameraWidget::~SingleCameraWidget() +{ + +} diff --git a/HX_CameraLoopPlay/SingleCameraWidget.h b/HX_CameraLoopPlay/SingleCameraWidget.h new file mode 100644 index 0000000..3db78e6 --- /dev/null +++ b/HX_CameraLoopPlay/SingleCameraWidget.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include "ui_SingleCameraWidget.h" + +class SingleCameraWidget : public QWidget +{ + Q_OBJECT + +public: + SingleCameraWidget(QWidget *parent = nullptr); + ~SingleCameraWidget(); + +private: + Ui::SingleCameraWidget ui; +}; diff --git a/HX_CameraLoopPlay/SingleCameraWidget.ui b/HX_CameraLoopPlay/SingleCameraWidget.ui new file mode 100644 index 0000000..22470b5 --- /dev/null +++ b/HX_CameraLoopPlay/SingleCameraWidget.ui @@ -0,0 +1,124 @@ + + + SingleCameraWidget + + + + 0 + 0 + 585 + 393 + + + + SingleCameraWidget + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + #widget_camera{ + border-image: url(:/CameraLoopPlay/Resource/image/rect.png); +} + + + + + 0 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + color: rgb(255, 255, 255); + + + + + + + + + + QLabel{ + font:75 25px; + color:#F0F0F0; + border:2px solid #AAAAAA; + background:transparent; +} +QLabel:focus{ + border:2px solid #00BB9E; + background:transparent; +} + + + + + + + + + + + + + + + + + + VideoWindowsComponent + QWidget +
component/videowindowscomponent.h
+ 1 +
+
+ + +
diff --git a/HX_CameraLoopPlay/cameradeviceinfo.h b/HX_CameraLoopPlay/cameradeviceinfo.h new file mode 100644 index 0000000..1746b42 --- /dev/null +++ b/HX_CameraLoopPlay/cameradeviceinfo.h @@ -0,0 +1,46 @@ +#ifndef CAMERADEVICEINFO_H +#define CAMERADEVICEINFO_H +#include + +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 diff --git a/HX_CameraLoopPlay/component/videowindowscomponent.cpp b/HX_CameraLoopPlay/component/videowindowscomponent.cpp new file mode 100644 index 0000000..0caacfc --- /dev/null +++ b/HX_CameraLoopPlay/component/videowindowscomponent.cpp @@ -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方法 +} diff --git a/HX_CameraLoopPlay/component/videowindowscomponent.h b/HX_CameraLoopPlay/component/videowindowscomponent.h new file mode 100644 index 0000000..1d98819 --- /dev/null +++ b/HX_CameraLoopPlay/component/videowindowscomponent.h @@ -0,0 +1,29 @@ +#ifndef VIDEOWINDOWSCOMPONENT_H +#define VIDEOWINDOWSCOMPONENT_H + +#include +#include +#include +#include + +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 diff --git a/HX_CameraLoopPlay/model/CameraDeviceInfo.h b/HX_CameraLoopPlay/model/CameraDeviceInfo.h new file mode 100644 index 0000000..e8ffceb --- /dev/null +++ b/HX_CameraLoopPlay/model/CameraDeviceInfo.h @@ -0,0 +1,46 @@ +#ifndef CAMERADEVICEINFO_H +#define CAMERADEVICEINFO_H +#include + +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