连接QQuickImageProvider

时间:2015-11-05 20:02:41

标签: c++ qt qml

我必须将QQuickImageProvider与类连接以传递图像提供者必须返回的图像,但我找不到这样做的方法。

我有一个名为proveorImagem.cpp的类,它实现了一个虚拟的requestImage函数,我还有一个名为processaImagem.cpp的类,它是在图像上执行修改的类。

provenorImagem类作为提供者传递给引擎:main.cpp中的engine.addImageProvider(" provenor",provenorImg)

我需要的是一种方法,将main.cpp中的提供程序中的插槽与processaImagem.cpp中的信号连接起来。这样做pro​​cessaImagem.cpp可以发送图像我必须返回Qml到provenorImagem.cpp并将其发送回Qml。

有人可以帮助我吗?

以下代码

的main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <QtQml>

#include "processaimagem.h"
#include "provedorimagem.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");

    QQmlApplicationEngine engine;

    provedorImagem *provedorImg = new provedorImagem;

    //------------  I have to create a connection here between the provider slot and a signal in processaImagem with the image to provide  -----------------

    engine.addImageProvider("provedor", provedorImg);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

processaImagem.h

#ifndef PROCESSAIMAGEM_H
#define PROCESSAIMAGEM_H

#include <QObject>
#include <QImage>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickImageProvider>

#include "provedorimagem.h"

class processaImagem : public QObject
{
    Q_OBJECT

public slots:
    QString recebeImagem(const QString &caminho);

public:
    processaImagem(QObject *parent = 0);

    QImage carregaImagem(const QString &caminho);

signals:
    void enviaImagem(QImage);
};

#endif // PROCESSAIMAGEM_H

processaImagem.cpp

#include "processaimagem.h"

#include <QDebug>

processaImagem::processaImagem(QObject *parent)
{

}

QString processaImagem::recebeImagem(const QString &caminho)
{
    QImage imagem = this->carregaImagem(caminho);

    QString caminhoRetorno;

    if(imagem.isNull())
    {
        qDebug() << "Erro ao receber a imagem";
    }
    else
    {
        qDebug() << "Imagem recebida";
        caminhoRetorno = "image://provedor/imagemEditada";
    }

    return caminhoRetorno;
}

QImage processaImagem::carregaImagem(const QString &caminho)
{
    QUrl caminhoImagem(caminho);
    QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
    QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host());
    QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase);

    QSize imageSize;
    QString imageId = caminhoImagem.path().remove(0, 1);
    QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize);

    if(imagem.isNull())
    {
        qDebug() << "Erro ao carregar a imagem";
        imagem = QImage();
    }
    else
    {
        qDebug() << "Imagem carregada";
    }

    return imagem;
}

provedorimagem.h

#ifndef PROVEDORIMAGEM_H
#define PROVEDORIMAGEM_H

#include <QImage>
#include <QQuickImageProvider>

class provedorImagem : public QQuickImageProvider
{
public:
    provedorImagem();

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

    void carregaImagem();

public slots:
    void carregaImagem(QImage imagemRecebida);

private:
    QImage imagem;
};

#endif // PROVEDORIMAGEM_H

provedorimagem.cpp

#include "provedorimagem.h"

#include <QDebug>

provedorImagem::provedorImagem() : QQuickImageProvider(QQuickImageProvider::Image)
{

}

QImage provedorImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    if(imagem.isNull())
    {
        qDebug() << "Erro ao prover a imagem";
    }
    else
    {
        qDebug() << "Imagem provida";
    }

    return imagem;
}

void provedorImagem::carregaImagem(QImage imagemRecebida)
{
    imagem = imagemRecebida;
}

3 个答案:

答案 0 :(得分:0)

要使图像提供者工作,需要实现以下方法之一:

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

来自上面的例子。

QImage provedorImagem::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    // the id has value like "imagemEditada" or the last word in URL
    if(imagem.isNull())
    {
        qDebug() << "Erro ao prover a imagem";
    }
    else if (caminhoRetorno.endsWith(id, Qt::CaseInsensitive)) // that will be a check for id after "provedor"
    {
        qDebug() << "Imagem provida";
        return imagem; // provide an image
    }
    return QImage(); // no match with id from url
}

你的QML代码应该有:

    Image {
        // // //
        source: "image://provedor/imagemEditada"
    }

Qt文档中有一个很好的完整example

@GuiDupas,从您更正的问题看来,您似乎想要识别所提供的图像。使用QString :: endsWith检查URL中的最后一个单词的方法当然是为了演示。

答案 1 :(得分:0)

我希望您尝试从qt(c ++)代码发送图像以在qml中显示。 请查看以下相机应用程序源。使用QQuickPaintedItem将相机图像传递给qml。

https://github.com/econsysqtcam/qtcam.git

查看videostreaming.cpp / videostreaming.h及其与qml的连接。希望有所帮助

答案 2 :(得分:0)

回答我自己的问题 问题解决了。以下是逐步解决方案:

1 - 创建一个继承自classQQuickImageProvider的{​​{1}},并在其中创建一个QObject成员Image,即要提供的图像。

(QImage)

实施class provedorImagem : public QObject, public QQuickImageProvider 方法。这是将图像返回到Qml

的方法
virtual requestImage

创建一个方法来加载提供者的图像以返回

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

现在将其设置为void provedorImagem::carregaImagem(QImage imagemRecebida) { imagem = imagemRecebida; } 文件

中的引擎图像提供程序
main.cpp

2 - 创建继承自provedorImagem *provedorImg = new provedorImagem; engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);

的其他class
QObject

在此类中,您必须实现一个方法,该方法将从class processaImagem : public QObject 提供程序获取图像,执行图像修改并返回修改后的图像。 PS:camerap_caminhoImagem我在收到property的{​​{1}}内创建的。{/ p>

processaImagem class

3 - 现在是主要部分。图像camera preview path提供程序方法必须从QImage processaImagem::carregaImagem() { QUrl caminhoImagem(p_caminhoImagem); QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine(); QQmlImageProviderBase *imageProviderBase = engine->imageProvider(caminhoImagem.host()); QQuickImageProvider *imageProvider = static_cast<QQuickImageProvider*>(imageProviderBase); QSize imageSize; QString imageId = caminhoImagem.path().remove(0, 1); QImage imagem = imageProvider->requestImage(imageId, &imageSize, imageSize); if(imagem.isNull()) { imagem = QImage(); } else { //Perform the modifications } return imagem; } 接收修改后的图像,以便将其提供给QML。要做到这一点,QML文件必须可以访问提供程序requestImage,因此,在processaImagem class文件中只需将指针作为class pointer

使QML可用
main.cpp

并将property注册为QML类型

engine.rootContext()->setContextProperty("ProvedorImagem", provedorImg);

现在我们将它链接到QML文件

processaImagem class

4 - 完成了。现在只需要提供者提供图像:

qmlRegisterType<processaImagem>("ProcessaImagemQml", 1, 0, "ProcessaImagem");