Qt 之C++发送图片到Qml显示,踏坑

项目背景

c++实现逻辑,qml实现内容展示,是qt的未来主流,这次实现的是c++拿到的图片,qml来是显示。
c++的图片是从摄像头获取,然后经过拼接和ocr,来实现实时显示扫描过程。

动态图片的展示

第一步重写QQuickImageProvider
首先定义一个类并继承于QQuickImageProvider,然后重新实现接口requestPixmap,如果需要传入QImage图片的话就重写requestImage接口

#include <QObject>
#include <QQuickItem>
#include <QQuickImageProvider>
#include <QImage>
class ImageProvider : public QQuickImageProvider
{
public:
    explicit ImageProvider(QObject *parent = nullptr);

    QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);

    QImage img;
};
ImageProvider::ImageProvider(QObject *parent)  : QQuickImageProvider(QQuickImageProvider::Image)
{
}

QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    return this->img;
}

QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
    return QPixmap::fromImage(this->img);
}

第二步 ,注册到qml

void OcrSingleton::registerImageProvider(QQmlEngine *engine)
{
    engine->addImageProvider(QLatin1String("OcrImage"), m_pImageProvider);
    qDebug() << "registerImageProvider";
}

第三步,在处理图片的类中,发送信号通知qml

void OcrSingleton::getOcrImage(const QImage &img)
{
    if(!img.isNull())
    {
        m_pImageProvider->img = img.copy(img.rect());
        emit callQmlRefreshImage();
    }
}
Image{
        id:img
        source: imgsource
        cache:false
        asynchronous: false
        fillMode: Image.PreserveAspectFit
        anchors.left: parent.left
        anchors.top: parent.top
        property bool counter: false
        function reload() {
            counter = !counter
            source = "image://OcrImage?id=" + counter
        }

        Connections{
            target: ocrManager
            onCallQmlRefreshImage:{
                img.reload()
            }
        }
    }

避坑

图片不动态刷新

注意设置Image 的 cache属性是 false

解决方法 1:

function reload() {
            counter = !counter
            source = "image://OcrImage?id=" + counter
        }

        Connections{
            target: ocrManager
            onCallQmlRefreshImage:{
                img.reload()
            }
        }

解决方法 2:
先将image的source 置空,再赋值

  Connections{
            target: ocrManager
            onCallQmlRefreshImage:{
                img.sourec = ""
                img.source ="image://OcrImage"
            }
        }

图片刷新过快的话,出现花屏

这就要考虑到图片是如何拿到的,比如下面两段代码,注意看其中区别

代码段1:

void OcrSingleton::getOcrImage(const QImage &img)
{
    if(!img.isNull())
    {
        m_pImageProvider->img = img;
        emit callQmlRefreshImage();
    }
}

代码段2:

void OcrSingleton::getOcrImage(const QImage &img)
{
    if(!img.isNull())
    {
        m_pImageProvider->img = img.copy(img.rect());
        emit callQmlRefreshImage();
    }
}

明白否?其实就涉及到了图片的深拷贝和浅拷贝问题,常用拷贝赋值的方式如下:

// 浅拷贝
QImage(uchar * data, int width, int height, Format format)
// 浅拷贝
QImage(const uchar * data, int width, int height, Format format)
// 浅拷贝
QImage(uchar * data, int width, int height, int bytesPerLine, Format format)
// 浅拷贝
QImage(const uchar * data, int width, int height, int bytesPerLine, Format format)
// 深拷贝
QImage QImage::copy(const QRect & rectangle = QRect()) const
// 浅拷贝
QImage QImage::rgbSwapped() const
//浅拷贝
QImage &QImage::operator=(const QImage &image)

改成深拷贝后,完美解决刷新花屏问题

  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值