Qt下集成大华网络相机SDK示例开发

文章目录


前言

近期在Qt环境下进行大华网络相机的使用,发现官网下载的SDK中提供的示例没有Qt的demo,通过学习其提供的MFC示例代码,我在这里也实现了一个比较简单的Qt下调用大华网络相机的示例程序,并将相关代码展现出来以便大家学习,如有错误之处,欢迎大家批评指正。

项目效果


提示:以下是本篇文章正文内容,下面案例可供参考

一、下载并集成大华网络相机SDK

到大华官网进行下载:大华设备网络SDK,也可以通过文末我的百度网盘链接下载本示例使用到的SDK(建议直接官网进行下载,有详细的示例文档及函数接口说明)

在官网下根据项目需求选择对应的SDK,下面是本示例使用到的:

在集成该SDK时,我是把需要用到的h和lib文件打包在一个文件夹内,然后放在项目pro文件的同级目录下,然后在pro文件中添加下列代码:(也可以直接在Qt中通过添加库的方式进行集成)

c 复制代码
#SDK
INCLUDEPATH += $$PWD/SDK/Includes
DEPENDPATH += $$PWD/SDK/Includes
LIBS += -L$$PWD/SDK/Lib/ -ldhnetsdk

SDK文件夹内容如图(dll文件夹中存放程序运行时需要的dll,运行时需要放在exe同级目录下)

二、示例实现功能

在我的示例项目代码中有详细的注释,这里就不对各功能一一介绍了:

1.绑定窗口句柄实时显示相机数据:

c 复制代码
//开始
void Widget::on_pb_start_clicked()
{
    if(0 != m_lRealPlayHandle)
    {
        CLIENT_StopRealPlay(m_lRealPlayHandle);
        m_lRealPlayHandle = 0;

        ui->pb_start->setText("开始");
    }
    else
    {
        int nChannel = 0;
        HWND hWnd = reinterpret_cast<HWND>(ui->lb_show->winId());
        m_lRealPlayHandle = CLIENT_StartRealPlay(m_lLoginHandle, nChannel, hWnd, DH_RType_Realplay, NULL, NULL, NULL);
        if (0 == m_lRealPlayHandle)
        {
            QMessageBox::information(this,"提示","开始失败!");
            return;
        }
        ui->pb_start->setText("停止");
        CLIENT_RenderPrivateData(m_lRealPlayHandle, TRUE);
    }
}

2.开启智能事件订阅,绑定事件回调:

c 复制代码
//订阅
void Widget::on_pb_event_clicked()
{
    if (0 != m_lRealLoadHandle)
        {
            CLIENT_StopLoadPic(m_lRealLoadHandle);
            m_lRealLoadHandle = 0;
            ui->pb_event->setText("订阅");
        }
        else
        {
            int nChannel = 0;
            m_lRealLoadHandle = CLIENT_RealLoadPictureEx(m_lLoginHandle, nChannel, EVENT_IVS_ALL, TRUE, EventCallback, (LDWORD)this, NULL);
            if (m_lRealLoadHandle == 0)
            {
                QMessageBox::information(this,"提示","订阅失败!");
                return;
            }
            ui->pb_event->setText("停止订阅");
        }
}

//事件回调
int CALLBACK Widget::EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{
    if(0 == dwUser)
    {
        return -1;
    }

    //绊线入侵事件
    if(dwAlarmType == EVENT_IVS_CROSSLINEDETECTION)   //EVENT_IVS_HUMANTRAIT
    {
        //检查是否有有效的图像数据
        if (pBuffer == NULL || dwBufSize == 0)
        {
            LOGDEBUG<<"事件回调图像数据无效";
            return -1;
        }

        //保存图像
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        QMetaObject::invokeMethod(camera, [=]()
        {
            //这里SaveImage中有直接操作ui控件,所以需要使用QMetaObject::invokeMethod
            camera->SaveImage(pBuffer,dwBufSize);
        });
    }
    return 0;
}

3.主动抓图,触发抓图回调并保存图像:

c 复制代码
//抓图
void Widget::on_pb_get_clicked()
{
    if (0 != m_lLoginHandle)
    {
        //主动抓图
        SNAP_PARAMS snapparams = {0};
        snapparams.Channel = 0;
        snapparams.mode = 0;
        snapparams.CmdSerial = 0;
        BOOL flag = CLIENT_SnapPicture(m_lLoginHandle, snapparams);
        if (!flag)
        {
            QMessageBox::information(this,"提示","抓图失败!");
        }
        else
        {
            ui->pte_text->appendPlainText("开始抓图");
        }
    }
}

//抓图回调
void CALLBACK Widget::CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{
    //跨线程调用,相机回调函数是有另开子线程的
    QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
    QMetaObject::invokeMethod(camera, [=]()
    {
        //多个相机就需要
        //if(ILoginID == camera->m_lLoginHandle)
        {
            camera->OnOnePicture(ILoginID,pBuf,RevLen,EncodeType,CmdSerial);
        }
    });
}

//抓图
void Widget::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial)
{
    //检查输入合法性
    if(!pBuf || RevLen == 0)
    {
        LOGDEBUG<<"抓图图像数据无效";
        return;
    }

    //保存图像
    SaveImage(pBuf,RevLen);
}

//保存图像
bool Widget::SaveImage(BYTE *pBuffer, DWORD dwBufSize)
{
    //定义输出文件名
    static int num = 0;
    num++;
    char outputFileName[256];
    snprintf(outputFileName, sizeof(outputFileName), "output_image_%d.jpg", num);

    //打开文件以写入二进制数据
    FILE* file = fopen(outputFileName, "wb");
    if (file == NULL)
    {
        LOGDEBUG<<"图像保存失败!";
        return false;
    }

    //写入图像数据到文件
    fwrite(pBuffer, 1, dwBufSize, file);

    //关闭文件
    fclose(file);

    LOGDEBUG<<"图像保存成功!";
    ui->pte_text->appendPlainText("图像保存成功!");
    return true;
}

4.鼠标事件过滤,进行云台控制

c 复制代码
//事件过滤器
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched ==ui->lb_show)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        if (event->type() == QEvent::MouseButtonPress)
        {
            //鼠标按下,记录起点
            m_startPos = mouseEvent->pos();
            m_currentPos = m_startPos;
            m_drawing = true;
            return true;
        }
        else if (event->type() == QEvent::MouseMove && m_drawing)
        {
            //鼠标移动,更新终点并绘制临时矩形
            m_currentPos = mouseEvent->pos();
            return true;
        }
        else if (event->type() == QEvent::MouseButtonRelease && m_drawing)
        {
            //鼠标释放,绘制最终矩形
            m_drawing = false;
            m_currentPos = mouseEvent->pos();

            //坐标转换
            QRect winRect = ui->lb_show->rect();
            double xScale =  winRect.width() / 2560.0;
            double yScale =  winRect.height() / 1440.0;
            m_startPos = QPoint(m_startPos.x()/xScale,m_startPos.y()/yScale);
            m_currentPos = QPoint(m_currentPos.x()/xScale,m_currentPos.y()/yScale);
            UpDateShow(m_startPos,m_currentPos);
            return true;
        }
    }
    return QWidget::eventFilter(watched,event);
}

5.相机断线与重连回调:

c 复制代码
//设备断连回调
void CALLBACK Widget::DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
    if(0 != dwUser)
    {
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        camera->SetConnect(0);
    }
}

//设备重连回调
void CALLBACK Widget::ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
    if(0 != dwUser)
    {
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        camera->SetConnect(1);
    }
}

、、、、、、

三、示例完整代码

1.DahuaDemo.pro

c 复制代码
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h \

FORMS += \
    widget.ui

qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

#SDK
INCLUDEPATH += $$PWD/SDK/Includes
DEPENDPATH += $$PWD/SDK/Includes
LIBS += -L$$PWD/SDK/Lib/ -ldhnetsdk

2.widget.h

c 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QObject>
#include <QMessageBox>
#include <QPen>
#include <QPainter>
#include <QMouseEvent>
#include <QLabel>
#include <QRect>
#include <QTime>
#include <QTimer>
#include <QPointer>
#include <QDebug>

#include "dhnetsdk.h"

#define LOGDEBUG qDebug()<<QTime::currentTime().toString("[hh:mm:ss:zzz]")

using namespace std;

struct HUMAN_TRAIT_EVENT_INFO
{
    DEV_EVENT_HUMANTRAIT_INFO stuEvent;
    BYTE* pBuf;
    int nBufSize;
};

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void InitWidget();
    void InitNetSDK();

    void SetConnect(int type);
    bool SaveImage(BYTE *pBuffer, DWORD dwBufSize);
    void UpDateShow(const QPoint &start, const QPoint &end);

    void PtzExtControl(DWORD dwCommand, DWORD dwParam = 0);
    void OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial);

protected:
    bool eventFilter(QObject *watched, QEvent *event);

private:
    static void CALLBACK DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);
    static void CALLBACK ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);
    static void CALLBACK CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser);
    static int CALLBACK EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved);

private slots:
    void on_pb_login_clicked();
    void on_pb_start_clicked();
    void on_pb_event_clicked();
    void on_pb_get_clicked();

private:
    Ui::Widget *ui;

    LLONG m_lLoginHandle;      //登录句柄
    LLONG m_lRealPlayHandle;   //播放句柄
    LLONG m_lRealLoadHandle;   //订阅句柄

    int m_posX;   //水平坐标
    int m_posY;   //垂直坐标
    int m_posZoom;    //变倍
    bool m_drawing;   //绘制标志
    QPoint m_startPos;     //鼠标起点
    QPoint m_currentPos;   //鼠标当前点


};
#endif // WIDGET_H

3.widget.cpp

c 复制代码
#include "widget.h"
#include "ui_widget.h"

#pragma execution_character_set("utf-8")

//LLONG m_lHandle;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    InitWidget();
}

Widget::~Widget()
{
    delete ui;

    if(0 != m_lLoginHandle)
    {
        on_pb_login_clicked();
    }
    CLIENT_Cleanup();
}

//初始化界面
void Widget::InitWidget()
{
    m_lLoginHandle = 0;
    m_lRealPlayHandle = 0;
    m_lRealLoadHandle = 0;

    ui->le_ip->setText("192.168.1.108");
    ui->le_port->setText("37777");
    ui->le_user->setText("admin");
    ui->le_password->setText("12345678");
    ui->lb_show->installEventFilter(this);

    //初始化相机
    InitNetSDK();

}

//初始化相机
void Widget::InitNetSDK()
{
    //初始化
    BOOL ret = CLIENT_Init(DisConnect, (LDWORD)this);
    if (ret)
    {
        LOG_SET_PRINT_INFO  stLogPrintInfo = {sizeof(stLogPrintInfo)};
        CLIENT_LogOpen(&stLogPrintInfo);

        //初始化成功后设置网络参数
        //目前仅单独设置获取设备信息时间(部分设备因性能问题,没法在默认时间内完成,其他参数暂时保持默认)
        NET_PARAM stuNetParam = {0};
        stuNetParam.nGetDevInfoTime = 3000;
        stuNetParam.nPicBufSize = 10*1024*1024;
        CLIENT_SetNetworkParam(&stuNetParam);

        //设置回调
        CLIENT_SetSnapRevCallBack(CaptureCallback,(LDWORD)this);
        CLIENT_SetAutoReconnect(ReConnect, (LDWORD)this);
    }
    else
    {
        QMessageBox::information(this,"提示","初始化SDK失败!");
    }
}

//设置连接
void Widget::SetConnect(int type)
{
    if(type == 0)
    {
        LOGDEBUG<<"相机断连";
    }
    else
    {
        LOGDEBUG<<"相机重连";
    }
}

//保存图像
bool Widget::SaveImage(BYTE *pBuffer, DWORD dwBufSize)
{
    //定义输出文件名
    static int num = 0;
    num++;
    char outputFileName[256];
    snprintf(outputFileName, sizeof(outputFileName), "output_image_%d.jpg", num);

    //打开文件以写入二进制数据
    FILE* file = fopen(outputFileName, "wb");
    if (file == NULL)
    {
        LOGDEBUG<<"图像保存失败!";
        return false;
    }

    //写入图像数据到文件
    fwrite(pBuffer, 1, dwBufSize, file);

    //关闭文件
    fclose(file);

    LOGDEBUG<<"图像保存成功!";
    ui->pte_text->appendPlainText("图像保存成功!");
    return true;
}

//更新界面显示
void Widget::UpDateShow(const QPoint &start, const QPoint &end)
{
    QRect winRect = ui->lb_show->rect();   //窗口矩形区域

    //LOGDEBUG<<"start:"<<start<<"   end:"<<end;
    double xScale =  winRect.width() / 2560.0;
    double yScale =  winRect.height() / 1440.0;
    QPoint pointStart = QPoint(start.x()*xScale,start.y()*yScale);   //起始点
    QPoint pointEnd = QPoint(end.x()*xScale,end.y()*yScale);   //结束点
    //LOGDEBUG<<"pointStart:"<<pointStart<<"   pointEnd:"<<pointEnd;

    QPoint origin;
    QPoint sendPoint;

    //计算窗口中心点(Qt的坐标系以左上角为原点)
    origin.setX( (winRect.left() + winRect.right()) / 2 );
    origin.setY( (winRect.top() + winRect.bottom()) / 2 );

    //计算两点中点坐标
    int dx = (pointStart.x() + pointEnd.x()) / 2;
    int dy = (pointStart.y() + pointEnd.y()) / 2;

    //获取窗口尺寸(Qt推荐使用width()/height()方法)
    int width  = winRect.width();
    int height = winRect.height();

    //坐标映射:将中点坐标转换为标准化的设备坐标
    //注意:Qt的Y轴方向向下,根据具体需求可能需要符号处理
    sendPoint.setX( (dx - origin.x()) * 8192 * 2 / width );
    sendPoint.setY( (dy - origin.y()) * 8192 * 2 / height ); // 反转Y轴方向

    //计算拖动区域尺寸(允许负值)
    int width2  = pointEnd.x() - pointStart.x();
    int height2 = pointEnd.y() - pointStart.y();
    int multiple = 0;

    //计算面积比例(带方向)
    if (height2 != 0 && width2 != 0)
    {
        if (pointEnd.y() >= pointStart.y())
        {
            multiple = (width * height) / (width2 * height2);
        }
        else
        {
            multiple = -(width * height) / (width2 * height2);
        }
    }
    m_posX = sendPoint.x();
    m_posY = sendPoint.y();
    m_posZoom = multiple;
    //qDebug()<<"m_posX:"<<m_posX<<"   m_posY:"<<m_posY<<"   m_posZoom:"<<m_posZoom;
    PtzExtControl(DH_EXTPTZ_FASTGOTO);
}

//云台控制
void Widget::PtzExtControl(DWORD dwCommand, DWORD dwParam)
{
    if (0 == m_lLoginHandle)
    {
        return;
    }

    long param1=0,param2=0,param3 = 0;
    char param4[256]={0};
    char *pchPresetName = NULL;
    switch(dwCommand) {
        case DH_PTZ_POINT_MOVE_CONTROL:
                //Go to preset
                param1=0;
                param2=1;
                param3=0;
                break;
        case DH_PTZ_POINT_SET_CONTROL:
                //Add preset
                param1=0;
                param2=1;
                param3=0;
                break;
        case DH_EXTPTZ_FASTGOTO:   //快速定位
        case DH_EXTPTZ_EXACTGOTO:
            //3D intelligent position
            param1=m_posX;
            param2=m_posY;
            param3=m_posZoom;
            break;
        case DH_EXTPTZ_RESETZERO:
            param1=0;
            param2=0;
            param3=0;
            break;
        default:
            break;
    }
    BOOL bRet=CLIENT_DHPTZControlEx2(m_lLoginHandle,0,dwCommand,param1,param2,param3,FALSE,(void*)param4);
    if(bRet)
    {
        LOGDEBUG<<"移动成功!";
    }
    else
    {
        LOGDEBUG<<"移动失败!";
    }
}

//抓图
void Widget::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial)
{
    //检查输入合法性
    if(!pBuf || RevLen == 0)
    {
        LOGDEBUG<<"抓图图像数据无效";
        return;
    }

    //保存图像
    SaveImage(pBuf,RevLen);
}

//事件过滤器
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched ==ui->lb_show)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        if (event->type() == QEvent::MouseButtonPress)
        {
            //鼠标按下,记录起点
            m_startPos = mouseEvent->pos();
            m_currentPos = m_startPos;
            m_drawing = true;
            return true;
        }
        else if (event->type() == QEvent::MouseMove && m_drawing)
        {
            //鼠标移动,更新终点并绘制临时矩形
            m_currentPos = mouseEvent->pos();
            return true;
        }
        else if (event->type() == QEvent::MouseButtonRelease && m_drawing)
        {
            //鼠标释放,绘制最终矩形
            m_drawing = false;
            m_currentPos = mouseEvent->pos();

            //坐标转换
            QRect winRect = ui->lb_show->rect();
            double xScale =  winRect.width() / 2560.0;
            double yScale =  winRect.height() / 1440.0;
            m_startPos = QPoint(m_startPos.x()/xScale,m_startPos.y()/yScale);
            m_currentPos = QPoint(m_currentPos.x()/xScale,m_currentPos.y()/yScale);
            UpDateShow(m_startPos,m_currentPos);
            return true;
        }
    }
    return QWidget::eventFilter(watched,event);
}

//设备断连回调
void CALLBACK Widget::DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
    if(0 != dwUser)
    {
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        camera->SetConnect(0);
    }
}

//设备重连回调
void CALLBACK Widget::ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
    if(0 != dwUser)
    {
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        camera->SetConnect(1);
    }
}

//抓图回调
void CALLBACK Widget::CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{
    //跨线程调用,相机回调函数是有另开子线程的
    QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
    QMetaObject::invokeMethod(camera, [=]()
    {
        //多个相机就需要
        //if(ILoginID == camera->m_lLoginHandle)
        {
            camera->OnOnePicture(ILoginID,pBuf,RevLen,EncodeType,CmdSerial);
        }
    });
}

//事件回调
int CALLBACK Widget::EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{
    if(0 == dwUser)
    {
        return -1;
    }

    //绊线入侵事件
    if(dwAlarmType == EVENT_IVS_CROSSLINEDETECTION)   //EVENT_IVS_HUMANTRAIT
    {
        //检查是否有有效的图像数据
        if (pBuffer == NULL || dwBufSize == 0)
        {
            LOGDEBUG<<"事件回调图像数据无效";
            return -1;
        }

        //保存图像
        QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);
        QMetaObject::invokeMethod(camera, [=]()
        {
            //这里SaveImage中有直接操作ui控件,所以需要使用QMetaObject::invokeMethod
            camera->SaveImage(pBuffer,dwBufSize);
        });
    }
    return 0;
}

//登录
void Widget::on_pb_login_clicked()
{
    if (0 != m_lLoginHandle )
    {
        if (0 != m_lRealPlayHandle)
        {
            on_pb_start_clicked();
        }
        if (0 != m_lRealLoadHandle)
        {

        }

        CLIENT_Logout(m_lLoginHandle);
        m_lLoginHandle = 0;

        ui->pb_login->setText("登录");
    }
    else
    {
        NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;
        memset(&stInparam, 0, sizeof(stInparam));
        stInparam.dwSize = sizeof(stInparam);
        strncpy(stInparam.szIP, ui->le_ip->text().toLocal8Bit(), sizeof(stInparam.szIP) - 1);
        strncpy(stInparam.szPassword, ui->le_password->text().toLocal8Bit(), sizeof(stInparam.szPassword) - 1);
        strncpy(stInparam.szUserName, ui->le_user->text().toLocal8Bit(), sizeof(stInparam.szUserName) - 1);
        stInparam.nPort = ui->le_port->text().toInt();
        stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;

        NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;
        memset(&stOutparam, 0, sizeof(stOutparam));
        stOutparam.dwSize = sizeof(stOutparam);
        m_lLoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);

        if (0 != m_lLoginHandle)
        {
            ui->pb_login->setText("登出");
        }
        else
        {
            QMessageBox::information(this,"提示","登录失败!");
            m_lLoginHandle = 0;
        }
    }
}

//开始
void Widget::on_pb_start_clicked()
{
    if(0 != m_lRealPlayHandle)
    {
        CLIENT_StopRealPlay(m_lRealPlayHandle);
        m_lRealPlayHandle = 0;

        ui->pb_start->setText("开始");
    }
    else
    {
        int nChannel = 0;
        HWND hWnd = reinterpret_cast<HWND>(ui->lb_show->winId());
        m_lRealPlayHandle = CLIENT_StartRealPlay(m_lLoginHandle, nChannel, hWnd, DH_RType_Realplay, NULL, NULL, NULL);
        if (0 == m_lRealPlayHandle)
        {
            QMessageBox::information(this,"提示","开始失败!");
            return;
        }
        ui->pb_start->setText("停止");
        CLIENT_RenderPrivateData(m_lRealPlayHandle, TRUE);
    }
}

//订阅
void Widget::on_pb_event_clicked()
{
    if (0 != m_lRealLoadHandle)
        {
            CLIENT_StopLoadPic(m_lRealLoadHandle);
            m_lRealLoadHandle = 0;
            ui->pb_event->setText("订阅");
        }
        else
        {
            int nChannel = 0;
            m_lRealLoadHandle = CLIENT_RealLoadPictureEx(m_lLoginHandle, nChannel, EVENT_IVS_ALL, TRUE, EventCallback, (LDWORD)this, NULL);
            if (m_lRealLoadHandle == 0)
            {
                QMessageBox::information(this,"提示","订阅失败!");
                return;
            }
            ui->pb_event->setText("停止订阅");
        }
}

//抓图
void Widget::on_pb_get_clicked()
{
    if (0 != m_lLoginHandle)
    {
        //主动抓图
        SNAP_PARAMS snapparams = {0};
        snapparams.Channel = 0;
        snapparams.mode = 0;
        snapparams.CmdSerial = 0;
        BOOL flag = CLIENT_SnapPicture(m_lLoginHandle, snapparams);
        if (!flag)
        {
            QMessageBox::information(this,"提示","抓图失败!");
        }
        else
        {
            ui->pte_text->appendPlainText("开始抓图");
        }
    }
}

4.widget.ui

四、下载链接

我这里将使用到的SDK打包在百度网盘,链接:https://pan.baidu.com/s/1RvS1qxdlkw6leKyGMGrOzQ?pwd=xxcj

提取码: xxcj


总结

这个示例实现了Qt下调用大华网络相机SDK进行实时显示,相较于大华提供的demo也是精简了部分功能,详细的可以运行官网提供的demo进行学习。在本文中有写到对智能事件的订阅回调,这个是需要通过浏览器对网络相机进行配置的,可以查看使用说明书来进行配置哦。


hello:

共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考博客:使用QT对接大华网络摄像头SDK的示例程序(建议收藏)

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能16 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G16 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt