Загрузка из байтового массива в изображение в Qml - PullRequest
4 голосов
/ 28 апреля 2019

Я создал класс C ++ в Qt для чтения файлов и преобразования их в байтовый массив, чтобы я мог хранить их в базе данных,
как мне работать с данными байтового массива, например, установить источник изображения в qml, как правильно преобразовать этот байтовый массив в связанные типы в qml

вот мой класс:

#ifndef UFILE_H
#define UFILE_H

#include <QObject>
#include <QQuickItem>
class UFile : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QByteArray data READ data NOTIFY dataChanged)
    Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
    Q_PROPERTY(int length READ length)
public:
    explicit UFile(QObject *parent = nullptr);
    QByteArray data() const;
    QString path() const;
    int length() const;
    void setPath(QString &path);
    void readFile(QString &filePath);
signals:
    void dataChanged(QByteArray data);
    void pathChanged(QString path);
public slots:
private :
    QByteArray _data;
    QString _path;
};

#endif // UFILE_H

cpp:

#include "ufile.h"
#include <QDir>

UFile::UFile(QObject *parent) : QObject(parent)
{

}
QByteArray UFile::data() const{
    return _data;
}
QString UFile::path() const{
    return _path;
}
int UFile::length() const{
    int i =_data.count();
    return i;
}
void UFile::setPath(QString &path){
    if(_path== path){
        return;
    }
    _path = path;
    readFile(_path);
    Q_EMIT pathChanged(_path);
}

void UFile::readFile(QString &filePath){
    if(filePath!= ""){
        QString _fp = filePath;
        if(_fp.startsWith("file:///"))
            _fp = QUrl(filePath).toLocalFile();
        if(_fp!= ""){
            _fp = QDir::toNativeSeparators(_fp);
            QFile file(_fp);
            if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
                return ;
            QByteArray bytes;
            bytes = file.readAll();
            _data = bytes;
        }
    }
}

и в qml:

UFile{
    id:testfile
    path: "C:/icon.ico"
    onPathChanged: {
        console.log(path)
    }
    Component.onCompleted: {
        console.log(length)
    }
}

Я пытался загрузить QImage и установить источник изображения в qml с помощью этих строк, но он застрял

QImage img; 
img.loadFromData(bytes);

и в qml:

image.source = result of img.loadFromData

1 Ответ

2 голосов
/ 29 апреля 2019

Возможным решением является преобразование в base64, и для этого не следует использовать флаг QIODevice::Text, также я добавил улучшения, чтобы ваш код был более читабельным.

*. H

#ifndef UFILE_H
#define UFILE_H

#include <QObject>
class UFile : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QByteArray data READ data NOTIFY dataChanged)
    Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
    Q_PROPERTY(QString base64 READ base64 NOTIFY base64Changed)
    Q_PROPERTY(int length READ length)
public:
    explicit UFile(QObject *parent = nullptr);
    QByteArray data() const;
    QString path() const;
    int length() const;
    QString base64() const;

public Q_SLOTS:
    void setPath(const QString &path);
    void readFile(const QString &filePath);

Q_SIGNALS:
    void dataChanged();
    void pathChanged(const QString & path);
    void base64Changed();

private :
    QByteArray _data;
    QString _path;
    QByteArray m_base64;
};

#endif // UFILE_H

*. Cpp

#include "ufile.h"
#include <QDir>
#include <QUrl>

UFile::UFile(QObject *parent) : QObject(parent)
{

}
QByteArray UFile::data() const{
    return _data;
}
QString UFile::path() const{
    return _path;
}
int UFile::length() const{
    int i =_data.count();
    return i;
}
void UFile::setPath(const QString &path){
    if(_path== path){
        return;
    }
    _path = path;
    readFile(_path);
    Q_EMIT pathChanged(_path);
    Q_EMIT dataChanged();
    Q_EMIT base64Changed();
}

QString UFile::base64() const
{
    return _data.toBase64();
}

void UFile::readFile(const QString &filePath){
    if(!filePath.isEmpty()){
        QString _fp = filePath;
        if(_fp.startsWith("file:///"))
            _fp = QUrl(filePath).toLocalFile();
        if(!_fp.isEmpty()){
            _fp = QDir::toNativeSeparators(_fp);
            QFile file(_fp);
            if (!file.open(QIODevice::ReadOnly))
                return ;
            _data = file.readAll();
        }
    }
}

*. Qml


UFile{
    id: uifile
    path : "C:/icon.ico"
}
Image {
    source: uifile.base64.length > 0 ? "data:image/png;base64," + uifile.base64: ""
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...