qt中c++获取图片qml实时显示的方式1——继承QQuickPaintedItem

news2024/9/20 22:24:24

通过c++ opencv获取rtsp视频流,或者视频源,在qml上进行实时视频显示。

一、在QML中通过QQuickPaintedItem动态加载图片

在QML中,可以使用QQuickPaintedItem来创建自定义的可绘制项。通过继承QQuickPaintedItem类,我们可以在QML中动态加载图片并进行绘制。在本篇博客中,我们将学习如何使用QQuickPaintedItem加载并绘制图片。

1. opecv 获取视频流图片

.pro文件中引入opencv

#windows
INCLUDEPATH +=D:\soft\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include
              D:\soft\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include\opencv
              D:\soft\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\include\opencv2


LIBS +=D:\soft\opencv3.4.0\OpenCV-MinGW-Build-OpenCV-3.4.5\x86\mingw\bin\libopencv_*.dll

创建一个线程类myThread用于获取图片
myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include "QThread"
#include <QTimer>
#include <QImage>
#include <QMutex>

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/types_c.h>

#include<QtNetwork/QNetworkRequest>
#include<QtNetwork/QNetworkReply>
#include<QtNetwork/QNetworkAccessManager>

class myThread : public QThread
{
    Q_OBJECT

public:
    explicit myThread(QObject *parent = nullptr);
    myThread(QString url);

protected:
    void run() override;


private:

    cv::VideoCapture video;         // 视频抓取
    cv::Mat src_frame;              // mat类用于存储矩阵类型数据,这里用来存储图像
    QString rtsp;                   // rtsp地址
    bool isStop=false;              // 线程是否运行
    QImage image;

    QNetworkAccessManager * manager;


signals:

    void sendArray(QImage qimg); // 发送图片的信号
    void sendImg(QImage qimg);         // 发送空白图片

public slots:

    void getFrame();            // 获取图像
    void closeFrame();          // 关闭画面
    void closeThread();         // 关闭线程
};

#endif // MYTHREAD_H

myThread.cpp

#include "mythread.h"
#include "QDebug"


myThread::myThread(QObject *parent) : QThread(parent)
{

    manager=new QNetworkAccessManager(this);
}

myThread::myThread(QString url)
{
    rtsp=url;

}

void myThread::run()
{

    qDebug() << "线程开始执行:"<< QThread::currentThread()<<rtsp;
    //  rtsp读取网络视频
    video=cv::VideoCapture(rtsp.toStdString());
    if(video.isOpened())
    {
        while (!isStop) {
            getFrame();
            msleep(25);
        }
        if(isStop){
            closeFrame();
            isStop=false;
        }
    }
}

// 关闭线程
void myThread::closeThread(){

    isStop=true;
    qDebug() << __FUNCTION__;
}

// 关闭画面
void myThread::closeFrame(){
    qDebug() << __FUNCTION__;
    emit sendImg(QImage(":/Image/Button/013.png"));
}

// 图像处理
void myThread::getFrame()
{

    video>>src_frame; //从视频取帧
    // mat to qimage
    if(src_frame.rows>0 && src_frame.cols>0){
        if(src_frame.channels() == 3) {
            // RGB image
            cvtColor(src_frame,src_frame,CV_BGR2RGB);
            image = QImage((const uchar*)(src_frame.data),  //(const unsigned char*)
                           src_frame.cols,src_frame.rows,
                           src_frame.cols*src_frame.channels(),   //new add
                           QImage::Format_RGB888);
        }

        else {
            // gray image
            image = QImage((const uchar*)(src_frame.data),
                           src_frame.cols,src_frame.rows,
                           src_frame.cols*src_frame.channels(),
                           QImage::Format_Indexed8);
        }

        // 发送信号
        emit sendArray(image);
    }else{
        qDebug() << __FUNCTION__<<"null";

    }
}



2. 创建自定义绘制项–ShowImage.h

首先,我们需要创建一个自定义的绘制项类。在这个类中,我们将重写QQuickPaintedItempaint方法来实现绘制逻辑。

ShowImage.h

#ifndef SHOWIMAGE_H
#define SHOWIMAGE_H

#include <QObject>
#include <QQuickPaintedItem>
#include <QImage>
#include <QPainter>

#include <mythread.h>

// qml 实时加载图片第一种方式--继承QQuickPaintedItem,自定义绘制
class ShowImage : public QQuickPaintedItem
{
    Q_OBJECT
public:
    explicit ShowImage(QQuickItem *parent = nullptr);

public slots:
    void updateImage(const QImage &);
    void start_camera(QString rtsp);
    void close_camera();

signals:
    void close_thread();

protected:
    void paint(QPainter *painter);

private:
    QImage m_imageThumb;
    QImage image_null=QImage(":/image/test.png");  // 默认图片
    myThread *m_thread=nullptr;  

};

#endif // SHOWIMAGE_H

3. 实现自定义绘制项

接下来,我们需要实现自定义绘制项的逻辑。
ShowImage.cpp

#include "showimage.h"

ShowImage::ShowImage(QQuickItem *parent)
{
    //默认图片
    m_imageThumb = image_null;
}

// 更新图片
void ShowImage::updateImage(const QImage &image)
{
    m_imageThumb = image;
    update();
}
// 开启视频捕获
void ShowImage::start_camera(QString rtsp)
{
    if(m_thread!=nullptr){
        close_camera();
    }
    m_thread=new myThread(rtsp);
    connect(m_thread,&myThread::sendArray,this,&ShowImage::updateImage);
    connect(m_thread,&myThread::sendImg,this,&ShowImage::updateImage);
    connect(this,&ShowImage::close_thread,m_thread,&myThread::closeThread);
    m_thread->start();

}
// 关闭视频捕获
void ShowImage::close_camera()
{
    qDebug() <<__FUNCTION__;
    emit close_thread();
    if(m_thread!=nullptr){
        m_thread->quit();
        m_thread->wait();
        delete m_thread;
        m_thread=nullptr;
    }
}

// 图片绘制
void ShowImage::paint(QPainter *painter)
{
    if(!m_imageThumb.isNull()){
        painter->drawImage(this->boundingRect(), m_imageThumb);
    }else{
        painter->drawImage(this->boundingRect(), QImage(image_null));
    }
}




4. 在main.cpp中注册自定义绘制类

main.cpp中注册自定义类给qml使用

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include <showimage.h>
#include "myimageprovider.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    // 获取上下文对象
    QQmlContext *context=engine.rootContext();
    // 注册自定义类
    qmlRegisterType<ShowImage>("ShowImage",1,0,"ShowImage");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    
    return app.exec();
}

5. qml中使用自定义绘制类

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

import ShowImage 1.0  // 导入自定义模块
Window {
    visible: true
    width: screenW
    height: 480
    title: qsTr("Hello World")

    // 第一种方式--使用自定义模块
    ShowImage{
        anchors.fill: parent
        id : showimg
        transformOrigin: Item.Center
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }

    Button {
        id:ok
        text: "相机"
        anchors.left: parent.left
        anchors.leftMargin: 20
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 50
        width: parent.width*0.2
        height: 50

        signal start_time_qml()   // 定义信号
        Connections {			  // 连接信号与槽
            target: ok
            onStart_time_qml: {
                showimg.start_camera("rtsp://admin:abcd1234@192.168.1.104/smart265/ch1/main/av_stream")
            }
        }
        onClicked: {
            ok.start_time_qml()
        }
    }

    Button {
        id:video
        text: "视频源"
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 50
        width: parent.width*0.2
        height: 50
        x:parent.width*0.32

        signal start_video_qml()
        Connections {
            target: video
            onStart_video_qml: {
                showimg.start_camera("H:\\360MoveData\\Users\\Administrator\\Desktop\\11.mp4")
            }
        }
        onClicked: {
            video.start_video_qml()
        }
    }

    Button {
        id:clear
        text: "关闭"
        anchors.right: parent.right
        anchors.rightMargin: 20
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 50
        width: parent.width*0.2
        height: 50
        x:parent.width*0.62

        signal clear_time_qml()
        Connections {
            target: clear
            onClear_time_qml: {
                showimg.close_camera()
            }
        }
        onClicked: {
            clear.clear_time_qml()
        }
    }
}

6. 运行程序

现在,你可以运行应用程序并点击对应按钮来动态加载并显示图片。当你点击按钮时,ShowImage将使用updateImage方法加载指定路径的图片,并将其绘制到界面上。

在这里插入图片描述

以播放视频为例:

qml 实时显示

这就是在QML中通过QQuickPaintedItem动态加载图片的基本步骤。你可以根据需要进一步定制自定义绘制项的功能和外观。

希望本篇博客对你有所帮助!如果你有任何问题,请随时提问。

源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/691060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

这些面试攻略给你2023测试面试带来最强力的支持

在boss和拉钩上投了有几十份简历&#xff0c;其中70%未读状态&#xff0c;30%已读&#xff0c;已读的一半回复要求发送附件简历&#xff0c;然后这周接到面试的有七、八家公司&#xff0c;所以&#xff0c;当前这个大环境真的难 这半个月来&#xff0c;每天安排三到四场面试&a…

自学黑客(网络安全),一般人我劝你还是算了吧(自学网络安全学习路线--第八章 恶意软件概念及防范)【建议收藏】

文章目录 一、自学网络安全学习的误区和陷阱二、学习网络安全的一些前期准备三、自学网络安全学习路线一、恶意软件分类1、分类依据2、获取远程控制权类3、维持远程控制权类4、完成特定业务逻辑类 二、恶意软件运行症状1、查看网络连接2、查看系统进程3、查看隐藏文件 三、恶意…

PACS/RIS医学影像管理系统源码 提供先进图像处理和算法

PACS&#xff08;医学影像存档与通信系统&#xff09;主要应用于医学影像的存储、传输和显示。它可以使医生突破胶片的局限&#xff0c;对病人的影像进行全方位的处理和观察&#xff0c;以便得出更准确的诊断。同时&#xff0c;PACS可以节省大量的胶片&#xff0c;降低成本。医…

定积分与几何应用

定积分与几何应用 何谓定积分&#xff1f; ∫ a b f ( x ) d x \int_a^bf(x)dx ∫ab​f(x)dx需满足 a a a、 b b b有限&#xff08;不是无穷&#xff09;且 f ( x ) f(x) f(x)有界 定积分的计算主要依靠NL公式即牛顿莱布尼茨公式 定积分是否存在于原函数是否存在无关 定积分计…

骑士周游问题及优化

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/java-tutorial 】或者公众号【AIShareLab】回复 java 也可获取。 文章目录 骑士周游问题算法优化意义经典算法面试题-骑士周游问题马踏棋盘算法介绍 骑士周游问题的解决步骤和思路分析 骑士周游问题…

什么是哈希表

哈希表 目录 哈希表哈希函数哈希碰撞拉链法线性探测法常见的三种哈希结构总结 首先什么是 哈希表&#xff0c;哈希表&#xff08;英文名字为Hash table&#xff0c;国内也有一些算法书籍翻译为散列表&#xff0c;大家看到这两个名称知道都是指hash table就可以了&#xff09;。…

Unity3D:Hierarchy 窗口

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 Hierarchy 窗口 打开 Unity 新项目时的默认 Hierarchy 窗口视图 Hierarchy 窗口显示场景中的每个游戏对象&#xff0c;如模型、摄像机或预制件。 可以使用 Hierarchy 窗口对场景中…

Nginx | 苹果电脑Mac安装和验证Nginx服务过程记录

common wx&#xff1a;CodingTechWork&#xff0c;一起学习进步。 引言 本文主要总结如何在Mac电脑上进行Nginx服务的安装&#xff0c;重点讲解使用brew命令进行安装和验证的过程及问题记录。 安装步骤 安装过程记录 查看nginx信息 首先使用命令brew info nginx进行本机ng…

网络规划工具

对于各种规模的企业和组织来说&#xff0c;应对安全威胁和可靠的网络性能至关重要。战略性地投资有效的网络监控解决方案可以节省时间和成本&#xff0c;减少停机时间并提高员工的生产力&#xff0c;还可以让管理员专注于重要的事情。重要的是要了解&#xff0c;随着业务的增长…

JAVA大作业——网络在线对战游戏——坦克大战

目录 大作业要求 实机演示 主机环回地址布置连接演示 多人联机对战演示 WASD控制坦克移动和按J键发射炮弹攻击 攻击到敌人后会爆炸并且消灭敌人 按下C键设置IP主机连接 大作业要求 简单的小游戏 要求1&#xff1a;能够实现例如贪吃蛇、坦克大战、俄罗斯方块等小游戏&#x…

红帽:多云和AI时代,开放混合云是最优选择

随着云计算市场群雄割据的格局逐渐定型&#xff0c;混合多云的环境已经成为大势所趋。而近年来AI人工智能技术的高速发展&#xff0c;则进一步为技术创新注入了澎湃动力。 那么问题就来了&#xff1a;在这个多云和AI大行其道的时代&#xff0c;企业应该选择什么样的云平台&…

删除PDF页面的10个操作工具方法分享

PDF被广泛用于各种目的&#xff0c;包括共享学术文件、专业报告&#xff0c;甚至个人文件。然而&#xff0c;有时您可能会发现需要从PDF中删除一些页面。虽然有很多付费软件可供选择&#xff0c;但也有很多免费删除PDF页面的方法。在这篇文章中&#xff0c;我们将讨论10种免费删…

这所广东的985录取平均分387分,复录比高达3.5,单科线55分!

一、学校及专业介绍 中山大学&#xff08;Sun Yat-sen University&#xff09;&#xff0c;简称“中大”&#xff0c;位于广东省&#xff0c;位列国家“双一流”、“985工程”、“211工程”&#xff0c;学校由广州、珠海、深圳三个校区&#xff0c;博士后科研流动站44个&#x…

CentOS7安装部署OpenVidu

1&#xff1a;安装Docker 参考&#xff1a;Centos7 安装 Docker_zzhongcy的博客-CSDN博客 2&#xff1a;安装OpenVidu 2.1、OpenVidu 简介 OpenVidu Server&#xff08;openvidu-server)&#xff1a;是openvidu平台的大脑&#xff0c;负责信号层。Kurento Media Server(kms)…

软件测试技能,JMeter压力测试教程,批量注册测试账号(计数器的使用)(十二)

一、前言 当我们jmeter压测的时候&#xff0c;需要准备一批测试账号&#xff0c;可以先批量注册一些用户&#xff0c;这些用户名称按固定格式 注册的用户不能重复并且需要自增&#xff0c;那么可以使用计数器来实现 二、添加注册请求 我想批量注册100个账号&#xff0c;账号…

【uniapp微信小程序footer】不满一屏固定显示在底部,超出一屏随页面滚动

<template><view class"wrapper"><view class"main">...</view><view class"footer">xx智慧农场</view></view > </template> <style>page {height: 100%;}.wrapper {height: 100%;}.ma…

高德地图的使用

JS API 结合 Vue 使用 高德地图 jsapi 下载、引入 npm add amap/amap-jsapi-loaderimport AMapLoader from amap/amap-jsapi-loader 使用2.0版本的loader需要在window对象下先配置 securityJsCode JS API 安全密钥使用 JS API 使用 script 标签同步加载增加代理服务器设置…

不定长(可变) 位置参数 *args和关键字参数 **kwargs 详解

位置参数&#xff1a; 传参时前面不带 "变量名", 顺序不可变, 按顺序赋给相应的局部变量def test(one,two,three):print(one - two * three)test(1,2,3) def test(one,two,three):print(one - two * three)test(3,2,1) 注意位置参数&#xff0c;需要注意 1 、 不…

STM32外设系列—BH1750

文章目录 一、BH1750简介二、BH1750原理图三、BH1750数据手册3.1 指令集3.2 IIC通信读/写 四、BH1750程序设计4.1 IIC程序4.2 BH1750初始化程序4.3 读取BH1750测量结果4.4 获取光照强度4.5 相关宏定义 五、应用实例六、拓展应用6.1 实时调节LED亮度6.2 实时调整颜色阈值 一、BH…

【Flutter】 Flutter 状态管理 BLoC 简明使用指南

文章目录 一、前言二、Flutter BLoC 的安装和配置三、Flutter BLoC 的基本使用四、Flutter BLoC 的简单示例五、总结 一、前言 &#x1f389;想要精通 Flutter&#xff0c;掌握更多技巧和最佳实践&#xff1f;好消息来了&#xff01;&#x1f449; Flutter专栏->Flutter De…