i created a c++ class in Qt to read files,and convert them to byte array so i can store them in database ,
how can i deal with byte array data for example setting image source in qml ,what is the correct way of converting this byte array to related types in qml
here is my class:
#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;
}
}
}
and in qml :
UFile{
id:testfile
path: "C:/icon.ico"
onPathChanged: {
console.log(path)
}
Component.onCompleted: {
console.log(length)
}
}
i tried to load QImage and set Image source in qml with this lines but it stuck
QImage img;
img.loadFromData(bytes);
and in qml:
image.source = result of img.loadFromData
A possible solution is to convert to base64, and for this you should not use the flag QIODevice::Text
, also I have added improvements so that your code is more readable.
*.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: ""
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With