I'm having some issues understanding how to display an image stored in a database in QML I would like to use a C++ model to do this. I believe from what I seen I will need an QQuickImageProvider and to over ride the requestImage() method.
Not quite sure how to set up the Image provider - subclass the image provider and over ride requestImage() ?
Not sure how to use the model and Image provider to display image in QML scrollView - model combines with ImageProvider to display image ?
I have a drop list for displaying the images name and once a user selects a image from the list I want the image to load into a scroll view...
I set up my database schema as such:
"CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)"
"CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)"
To copy to clipboard, switch view to plain text mode
QML code
Item {
id:checkList_item
implicitHeight: 600
implicitWidth: 1000
signal exit()
Rectangle {
id: checkList_Rect
anchors.fill: parent
radius: 10
border.width:4
border.color: "black"
layer.enabled: true
enabled: true
opacity: enabled ? 1.0 : .3
layer.effect: DropShadow {
horizontalOffset: 8
verticalOffset: 8
radius: 8.0
samples: 16
color: "#80000000"
source: checkList_Rect
}
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
}
GradientStop {
position: 1
color: "#262626"
}
}
//---Saves check list to database---//
Action{
id: action_saveCheckList
onTriggered: {
/*
* saves check list to database
* saves the date the check list was verfied
* operator that verified check list
* Engineer who verified check list
*/
}
}
//---Closes Check List Dialog---//
Action{
id: action_exit
enabled:!inSequence
onTriggered: {
//checkList_item.exit();
window_contents.state = ""
}
}
//---Calls function after QML loads---//
Component.onCompleted: {
//---calls initalize function--//
PictureModel.init();
}
FocusScope{
id: focusScope1
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
anchors.fill:parent
//---List Check List Currently in the database---//
ComboBox {
id: checkList_comboBox
width: 130
height: 48
anchors.left: parent.left
anchors.leftMargin: 50
anchors.top: parent.top
anchors.topMargin: 41
implicitHeight: 30
implicitWidth: 130
KeyNavigation.tab: addCheckListItem
activeFocusOnTab: true
model: PictureModel
textRole: "picName"
style: userListCombo
Keys.onReturnPressed: {
checkList_comboBox.focus = false;
addItem.focus = true;
}
}
//---Component for comboBox Style---//
Component {
id: userListCombo
ComboBoxStyle {
id: userListcomboxstyle
textColor: "black"
selectionColor: "yellow"
selectedTextColor: "black"
background: Rectangle {
id: comboBackgroundRect
color: "#f9f9f9"
radius: 8
height: 22
width: 67
border.color: control.activeFocus ? "yellow" : "#242424"
border.width: control.activeFocus ? 4 : 2
Image {
id: name
width: 12
height: 12
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 5
source: "/combo_expand.png"
}
}
}
}
//---Rect to hold Image---//
Rectangle {
id: chekListView_rect
radius: 8
width: 1000
height: 400
anchors.left: parent.left
anchors.leftMargin: 10
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -5
border{
color: "black"
width: 3
}
//---Adds ScrollBars---//
ScrollView{
id: userEvent_scrollView
anchors.fill: parent
//---Enables flickable Area---//
flickableItem.interactive: true
verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
style: edit_scrollbar_style
//---Display image from C++ model---//
Image{
//source:
}
}
}
//---Custom ScrollBar Component---//
Component{
id: edit_scrollbar_style
ScrollViewStyle {
transientScrollBars: false
handle: Item {
implicitWidth: 17
implicitHeight: 25
Rectangle {
color: "#424246"
radius: 6
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 4
anchors.rightMargin: 4
anchors.bottomMargin: 6
}
}
decrementControl: Rectangle{
implicitWidth: 17
implicitHeight: 17
radius: 6
color:"#626262"
Image{
anchors.centerIn: parent
width: 15
height: 15
source: "up_arrow.png"
}
Rectangle {
implicitWidth: 17
implicitHeight: 5
color:"#626262"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
incrementControl: Rectangle{
implicitWidth: 17
implicitHeight: 17
radius: 6
color:"#626262"
Image{
anchors.centerIn: parent
width: 15
height: 15
source: "down_arrow.png"
}
Rectangle {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
implicitWidth: 17
implicitHeight: 5
color:"#626262"
}
}
scrollBarBackground: Rectangle {
implicitWidth: 17
implicitHeight: 25
color:"grey"
}
}
}
}
}
}
Item {
id:checkList_item
implicitHeight: 600
implicitWidth: 1000
signal exit()
Rectangle {
id: checkList_Rect
anchors.fill: parent
radius: 10
border.width:4
border.color: "black"
layer.enabled: true
enabled: true
opacity: enabled ? 1.0 : .3
layer.effect: DropShadow {
horizontalOffset: 8
verticalOffset: 8
radius: 8.0
samples: 16
color: "#80000000"
source: checkList_Rect
}
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
}
GradientStop {
position: 1
color: "#262626"
}
}
//---Saves check list to database---//
Action{
id: action_saveCheckList
onTriggered: {
/*
* saves check list to database
* saves the date the check list was verfied
* operator that verified check list
* Engineer who verified check list
*/
}
}
//---Closes Check List Dialog---//
Action{
id: action_exit
enabled:!inSequence
onTriggered: {
//checkList_item.exit();
window_contents.state = ""
}
}
//---Calls function after QML loads---//
Component.onCompleted: {
//---calls initalize function--//
PictureModel.init();
}
FocusScope{
id: focusScope1
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
anchors.fill:parent
//---List Check List Currently in the database---//
ComboBox {
id: checkList_comboBox
width: 130
height: 48
anchors.left: parent.left
anchors.leftMargin: 50
anchors.top: parent.top
anchors.topMargin: 41
implicitHeight: 30
implicitWidth: 130
KeyNavigation.tab: addCheckListItem
activeFocusOnTab: true
model: PictureModel
textRole: "picName"
style: userListCombo
Keys.onReturnPressed: {
checkList_comboBox.focus = false;
addItem.focus = true;
}
}
//---Component for comboBox Style---//
Component {
id: userListCombo
ComboBoxStyle {
id: userListcomboxstyle
textColor: "black"
selectionColor: "yellow"
selectedTextColor: "black"
background: Rectangle {
id: comboBackgroundRect
color: "#f9f9f9"
radius: 8
height: 22
width: 67
border.color: control.activeFocus ? "yellow" : "#242424"
border.width: control.activeFocus ? 4 : 2
Image {
id: name
width: 12
height: 12
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 5
source: "/combo_expand.png"
}
}
}
}
//---Rect to hold Image---//
Rectangle {
id: chekListView_rect
radius: 8
width: 1000
height: 400
anchors.left: parent.left
anchors.leftMargin: 10
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -5
border{
color: "black"
width: 3
}
//---Adds ScrollBars---//
ScrollView{
id: userEvent_scrollView
anchors.fill: parent
//---Enables flickable Area---//
flickableItem.interactive: true
verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
style: edit_scrollbar_style
//---Display image from C++ model---//
Image{
//source:
}
}
}
//---Custom ScrollBar Component---//
Component{
id: edit_scrollbar_style
ScrollViewStyle {
transientScrollBars: false
handle: Item {
implicitWidth: 17
implicitHeight: 25
Rectangle {
color: "#424246"
radius: 6
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 4
anchors.rightMargin: 4
anchors.bottomMargin: 6
}
}
decrementControl: Rectangle{
implicitWidth: 17
implicitHeight: 17
radius: 6
color:"#626262"
Image{
anchors.centerIn: parent
width: 15
height: 15
source: "up_arrow.png"
}
Rectangle {
implicitWidth: 17
implicitHeight: 5
color:"#626262"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
incrementControl: Rectangle{
implicitWidth: 17
implicitHeight: 17
radius: 6
color:"#626262"
Image{
anchors.centerIn: parent
width: 15
height: 15
source: "down_arrow.png"
}
Rectangle {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
implicitWidth: 17
implicitHeight: 5
color:"#626262"
}
}
scrollBarBackground: Rectangle {
implicitWidth: 17
implicitHeight: 25
color:"grey"
}
}
}
}
}
}
To copy to clipboard, switch view to plain text mode
Added after 20 minutes:
C++ here is the model code
header prototype
//---Data struct for stored checkLists---//
struct PictureModelStruct{
};
Q_OBJECT
public:
explicit PictureModel
(QObject *parent
= 0);
~PictureModel();
void setContext(QQmlContext* root);
Q_INVOKABLE void insertPic();
Q_INVOKABLE void displayPic();
enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
Q_INVOKABLE bool dbConnect();
Q_INVOKABLE void init();
Q_INVOKABLE bool selectPictureName();
signals:
void showBusy(bool busy_state);
public slots:
private:
//---Databse Class Instances---//
QList<PictureModelStruct> m_picList;
};
//---Data struct for stored checkLists---//
struct PictureModelStruct{
QString id;
QString picname;
QPixmap pic;
};
class PictureModel : public QAbstractListModel{
Q_OBJECT
public:
explicit PictureModel(QObject *parent = 0);
~PictureModel();
void setContext(QQmlContext* root);
Q_INVOKABLE void insertPic();
Q_INVOKABLE void displayPic();
enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
int rowCount(const QModelIndex & parent) const;
QHash<int, QByteArray> roleNames() const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
Q_INVOKABLE bool dbConnect();
Q_INVOKABLE void init();
Q_INVOKABLE bool selectPictureName();
signals:
void showBusy(bool busy_state);
public slots:
private:
//---Databse Class Instances---//
QList<PictureModelStruct> m_picList;
QSqlDatabase m_selectPictureDB;
};
To copy to clipboard, switch view to plain text mode
//---Constructor subclasses ListModel & ImageLoader---//
QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
}
}
//---Destructor---//
PictureModel::~PictureModel(){
}
//---init() is called after QML loads---//
void PictureModel::init(){
//insertPic();
displayPic();
selectPictureName();
}
//---Connect to BLOB database---//
bool PictureModel::dbConnect(){
//---check if database is connected---//
if(!m_selectPictureDB.isValid()){
qDebug() << "PictureModel::dbConnect() error in connecting to DB";
m_selectPictureDB
= QSqlDatabase::addDatabase("QSQLITE",
"conn5");
m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
m_selectPictureDB.open();
if(!tables.contains("picTable")){
q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
qDebug() << "PictureModel::dbConnect() created picTable";
}
}
else{
qDebug() <<"PictureModel::dbConnect() connected to DB" ;
m_selectPictureDB.open();
}
return m_selectPictureDB.isValid();
}
//---Inserts a pic into BLOB database
void PictureModel::insertPic(){
dbConnect();
qDebug() << image.size();
image.save(&buffer, "jpg");
bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
query.addBindValue(5);
query.addBindValue("flower");
query.addBindValue(inByteArray);
if(sqlBool){
if(query.exec()){
qDebug() << "PictureModel::insertPic() sql insert executed fine!";
}
}
else{
qDebug() << "PictureModel::isertPic() sql insert did not execute!";
}
}
//---Displays pic stored in BLOB database---//
void PictureModel::displayPic(){
dbConnect();
bool sqlBool;
sqlBool = query.prepare("SELECT pic FROM picTable");
if (sqlBool){
qDebug() << "prepare sql display pic executed fine!";
if(query.exec()){
qDebug() << "execute sql display pic executed fine!";
}
else{
qDebug() << "execute sql display pic did not execute";
}
}
else{
qDebug() << "prepare sql display pic did not execute";
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (query.next()){
picList.id = query.value(0).toString();
picList.picname = query.value(1).toString();
outByteArray = query.value(2).toByteArray();
picList.
pic = QPixmap::fromImage(QImage::fromData(outByteArray,
"jpg"));
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
}
//---Function is called in xmui.cpp---//
void PictureModel::setContext(QQmlContext* root){
//---Sets rootContext for model to be used in userListModel QML---//
root->setContextProperty("PictureModel", this);
}
int PictureModel
::rowCount(const QModelIndex &parent
) const{ Q_UNUSED(parent);
return m_picList.count();
}
QHash<int, QByteArray> PictureModel::roleNames() const{
QHash<int, QByteArray> roleNames;
roleNames.insert(nameRole, "picName");
return roleNames;
}
if (index.row() < 0 || index.row() >= m_picList.count()){
}
if(role == nameRole){
PictureModelStruct pList = m_picList.at(index.row());
text = pList.picname;
}
return text;
}
void PictureModel::addPicture(const PictureModelStruct &picList){
m_picList.insert(0, picList);
endInsertRows();
}
//---Selects name of pictures from DB for display---//
bool PictureModel::selectPictureName(){
dbConnect();
emit showBusy(true);
bool sqlBool;
sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
if(sqlBool){
if(selectQuery.exec()){
qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
}
}
else{
emit xmui
->alertMsg
(QMessageBox::Warning,
"Database selectPicture Error Message 1",
"Error: sql select script..."+selectQuery.
lastError().
text());
qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
return selectQuery.exec();
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (selectQuery.next()){
picList.picname = selectQuery.value(1).toString();
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
return selectQuery.exec();
}
//---Constructor subclasses ListModel & ImageLoader---//
PictureModel::PictureModel(QObject *parent) : QAbstractListModel(parent),
QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
}
QPixmap PictureModel::requestPixmap(const QString &id, QSize *size, const QSize &reqSize){
}
//---Destructor---//
PictureModel::~PictureModel(){
}
//---init() is called after QML loads---//
void PictureModel::init(){
//insertPic();
displayPic();
selectPictureName();
}
//---Connect to BLOB database---//
bool PictureModel::dbConnect(){
//---check if database is connected---//
if(!m_selectPictureDB.isValid()){
qDebug() << "PictureModel::dbConnect() error in connecting to DB";
m_selectPictureDB = QSqlDatabase::addDatabase("QSQLITE", "conn5");
m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
m_selectPictureDB.open();
QStringList tables = m_selectPictureDB.tables();
if(!tables.contains("picTable")){
QSqlQuery q("", m_selectPictureDB);
q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
qDebug() << "PictureModel::dbConnect() created picTable";
}
}
else{
qDebug() <<"PictureModel::dbConnect() connected to DB" ;
m_selectPictureDB.open();
}
return m_selectPictureDB.isValid();
}
//---Inserts a pic into BLOB database
void PictureModel::insertPic(){
dbConnect();
QImage image("flower3.jpg");
qDebug() << image.size();
QByteArray inByteArray;
QBuffer buffer(&inByteArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "jpg");
QSqlQuery query(m_selectPictureDB);
bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
query.addBindValue(5);
query.addBindValue("flower");
query.addBindValue(inByteArray);
if(sqlBool){
if(query.exec()){
qDebug() << "PictureModel::insertPic() sql insert executed fine!";
}
}
else{
qDebug() << "PictureModel::isertPic() sql insert did not execute!";
}
}
//---Displays pic stored in BLOB database---//
void PictureModel::displayPic(){
dbConnect();
QByteArray outByteArray;
QSqlQuery query(m_selectPictureDB);
bool sqlBool;
sqlBool = query.prepare("SELECT pic FROM picTable");
if (sqlBool){
qDebug() << "prepare sql display pic executed fine!";
if(query.exec()){
qDebug() << "execute sql display pic executed fine!";
}
else{
qDebug() << "execute sql display pic did not execute";
}
}
else{
qDebug() << "prepare sql display pic did not execute";
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (query.next()){
picList.id = query.value(0).toString();
picList.picname = query.value(1).toString();
outByteArray = query.value(2).toByteArray();
picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
}
//---Function is called in xmui.cpp---//
void PictureModel::setContext(QQmlContext* root){
//---Sets rootContext for model to be used in userListModel QML---//
root->setContextProperty("PictureModel", this);
}
int PictureModel::rowCount(const QModelIndex &parent) const{
Q_UNUSED(parent);
return m_picList.count();
}
QHash<int, QByteArray> PictureModel::roleNames() const{
QHash<int, QByteArray> roleNames;
roleNames.insert(nameRole, "picName");
return roleNames;
}
QVariant PictureModel::data(const QModelIndex &index, int role) const{
if (index.row() < 0 || index.row() >= m_picList.count()){
return QVariant();
}
QVariant text;
if(role == nameRole){
PictureModelStruct pList = m_picList.at(index.row());
text = pList.picname;
}
return text;
}
void PictureModel::addPicture(const PictureModelStruct &picList){
beginInsertRows(QModelIndex(), 0, 0);
m_picList.insert(0, picList);
endInsertRows();
}
//---Selects name of pictures from DB for display---//
bool PictureModel::selectPictureName(){
dbConnect();
emit showBusy(true);
QSqlQuery selectQuery(m_selectPictureDB);
bool sqlBool;
sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
if(sqlBool){
if(selectQuery.exec()){
qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
}
}
else{
emit xmui->alertMsg(QMessageBox::Warning, "Database selectPicture Error Message 1", "Error: sql select script..."+selectQuery.lastError().text());
qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
return selectQuery.exec();
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (selectQuery.next()){
picList.picname = selectQuery.value(1).toString();
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
return selectQuery.exec();
}
To copy to clipboard, switch view to plain text mode
updated header file
//---Data struct for stored checkLists---//
struct PictureModelStruct{
};
Q_OBJECT
public:
explicit PictureModel
(QObject *parent
= 0);
~PictureModel();
void setContext(QQmlContext* root);
Q_INVOKABLE void insertPic();
Q_INVOKABLE void displayPic();
enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
Q_INVOKABLE bool dbConnect();
Q_INVOKABLE void init();
Q_INVOKABLE bool selectPictureName();
signals:
void showBusy(bool busy_state);
public slots:
private:
//---Databse Class Instances---//
QList<PictureModelStruct> m_picList;
};
//---Data struct for stored checkLists---//
struct PictureModelStruct{
QString id;
QString picname;
QPixmap pic;
};
class PictureModel : public QAbstractListModel, QQuickImageProvider{
Q_OBJECT
public:
explicit PictureModel(QObject *parent = 0);
~PictureModel();
void setContext(QQmlContext* root);
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &reqSize);
Q_INVOKABLE void insertPic();
Q_INVOKABLE void displayPic();
enum pictureRoles{idRole= Qt::UserRole + 1, nameRole, picRole};
int rowCount(const QModelIndex & parent) const;
QHash<int, QByteArray> roleNames() const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
Q_INVOKABLE void addPicture(const PictureModelStruct &picList);
Q_INVOKABLE bool dbConnect();
Q_INVOKABLE void init();
Q_INVOKABLE bool selectPictureName();
signals:
void showBusy(bool busy_state);
public slots:
private:
//---Databse Class Instances---//
QList<PictureModelStruct> m_picList;
QSqlDatabase m_selectPictureDB;
};
To copy to clipboard, switch view to plain text mode
Added after 9 minutes:
thought about adding a call to requestImage() and pass it the id and image from the database...
requestPixmap
(picList.
id, picList.
pic,
QSize::scaled(20,
20, Qt
::IgnoreAspectRatio));
requestPixmap(picList.id, picList.pic, QSize::scaled(20,20, Qt::IgnoreAspectRatio));
To copy to clipboard, switch view to plain text mode
Added after 7 minutes:
change form pixMap to Image
Added after 25 minutes:
updated c++ functions
//---Constructor subclasses ListModel & ImageLoader---//
QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
}
Q_UNUSED(id);
Q_UNUSED(size);
Q_UNUSED(reqSize);
//return QImage::fromData(this->record(id.toInt(), "jpg"));
}
//---Destructor---//
PictureModel::~PictureModel(){
}
//---init() is called after QML loads---//
void PictureModel::init(){
//insertPic();
displayPic();
selectPictureName();
}
//---Connect to BLOB database---//
bool PictureModel::dbConnect(){
//---check if database is connected---//
if(!m_selectPictureDB.isValid()){
qDebug() << "PictureModel::dbConnect() error in connecting to DB";
m_selectPictureDB
= QSqlDatabase::addDatabase("QSQLITE",
"conn5");
m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
m_selectPictureDB.open();
if(!tables.contains("picTable")){
q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
qDebug() << "PictureModel::dbConnect() created picTable";
}
}
else{
qDebug() <<"PictureModel::dbConnect() connected to DB" ;
m_selectPictureDB.open();
}
return m_selectPictureDB.isValid();
}
//---Inserts a pic into BLOB database
void PictureModel::insertPic(){
dbConnect();
qDebug() << image.size();
image.save(&buffer, "jpg");
bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
query.addBindValue(5);
query.addBindValue("flower");
query.addBindValue(inByteArray);
if(sqlBool){
if(query.exec()){
qDebug() << "PictureModel::insertPic() sql insert executed fine!";
}
}
else{
qDebug() << "PictureModel::isertPic() sql insert did not execute!";
}
}
//---Displays pic stored in BLOB database---//
void PictureModel::displayPic(){
dbConnect();
bool sqlBool;
sqlBool = query.prepare("SELECT pic FROM picTable");
if (sqlBool){
qDebug() << "prepare sql display pic executed fine!";
if(query.exec()){
qDebug() << "execute sql display pic executed fine!";
}
else{
qDebug() << "execute sql display pic did not execute";
}
}
else{
qDebug() << "prepare sql display pic did not execute";
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (query.next()){
picList.id = query.value(0).toString();
picList.picname = query.value(1).toString();
outByteArray = query.value(2).toByteArray();
picList.
pic = QPixmap::fromImage(QImage::fromData(outByteArray,
"jpg"));
addPicture(picList);
//requestImage(picList.id, QSize(20, 20), QSize(20, 20));
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
}
//---Function is called in xmui.cpp---//
void PictureModel::setContext(QQmlContext* root){
//---Sets rootContext for model to be used in userListModel QML---//
root->setContextProperty("PictureModel", this);
}
int PictureModel
::rowCount(const QModelIndex &parent
) const{ Q_UNUSED(parent);
return m_picList.count();
}
QHash<int, QByteArray> PictureModel::roleNames() const{
QHash<int, QByteArray> roleNames;
roleNames.insert(nameRole, "picName");
return roleNames;
}
if (index.row() < 0 || index.row() >= m_picList.count()){
}
if(role == nameRole){
PictureModelStruct pList = m_picList.at(index.row());
text = pList.picname;
}
return text;
}
void PictureModel::addPicture(const PictureModelStruct &picList){
m_picList.insert(0, picList);
endInsertRows();
}
//---Selects name of pictures from DB for display---//
bool PictureModel::selectPictureName(){
dbConnect();
emit showBusy(true);
bool sqlBool;
sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
if(sqlBool){
if(selectQuery.exec()){
qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
}
}
else{
emit xmui
->alertMsg
(QMessageBox::Warning,
"Database selectPicture Error Message 1",
"Error: sql select script..."+selectQuery.
lastError().
text());
qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
return selectQuery.exec();
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (selectQuery.next()){
picList.picname = selectQuery.value(1).toString();
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
return selectQuery.exec();
}
//---Constructor subclasses ListModel & ImageLoader---//
PictureModel::PictureModel(QObject *parent) : QSqlQueryModel(parent),
QQuickImageProvider(QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading){
}
QImage PictureModel::requestImage(const QString &id, QSize *size, const QSize &reqSize){
Q_UNUSED(id);
Q_UNUSED(size);
Q_UNUSED(reqSize);
//return QImage::fromData(this->record(id.toInt(), "jpg"));
}
//---Destructor---//
PictureModel::~PictureModel(){
}
//---init() is called after QML loads---//
void PictureModel::init(){
//insertPic();
displayPic();
selectPictureName();
}
//---Connect to BLOB database---//
bool PictureModel::dbConnect(){
//---check if database is connected---//
if(!m_selectPictureDB.isValid()){
qDebug() << "PictureModel::dbConnect() error in connecting to DB";
m_selectPictureDB = QSqlDatabase::addDatabase("QSQLITE", "conn5");
m_selectPictureDB.setDatabaseName(Paths::root() + "/pictures.db");
qDebug() << "PictureModel::dbConnect() database connection path: "+Paths::root()+"/pictures.db";
m_selectPictureDB.open();
QStringList tables = m_selectPictureDB.tables();
if(!tables.contains("picTable")){
QSqlQuery q("", m_selectPictureDB);
q.exec("CREATE TABLE IF NOT EXISTS picTable (id INT PRIMARY KEY, picName TEXT, pic BLOB)");
qDebug() << "PictureModel::dbConnect() created picTable";
}
}
else{
qDebug() <<"PictureModel::dbConnect() connected to DB" ;
m_selectPictureDB.open();
}
return m_selectPictureDB.isValid();
}
//---Inserts a pic into BLOB database
void PictureModel::insertPic(){
dbConnect();
QImage image("flower3.jpg");
qDebug() << image.size();
QByteArray inByteArray;
QBuffer buffer(&inByteArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "jpg");
QSqlQuery query(m_selectPictureDB);
bool sqlBool = query.prepare("INSERT INTO picTable (id, picName, pic) VALUES (?, ?, ?)");
query.addBindValue(5);
query.addBindValue("flower");
query.addBindValue(inByteArray);
if(sqlBool){
if(query.exec()){
qDebug() << "PictureModel::insertPic() sql insert executed fine!";
}
}
else{
qDebug() << "PictureModel::isertPic() sql insert did not execute!";
}
}
//---Displays pic stored in BLOB database---//
void PictureModel::displayPic(){
dbConnect();
QByteArray outByteArray;
QSqlQuery query(m_selectPictureDB);
bool sqlBool;
sqlBool = query.prepare("SELECT pic FROM picTable");
if (sqlBool){
qDebug() << "prepare sql display pic executed fine!";
if(query.exec()){
qDebug() << "execute sql display pic executed fine!";
}
else{
qDebug() << "execute sql display pic did not execute";
}
}
else{
qDebug() << "prepare sql display pic did not execute";
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (query.next()){
picList.id = query.value(0).toString();
picList.picname = query.value(1).toString();
outByteArray = query.value(2).toByteArray();
picList.pic = QPixmap::fromImage(QImage::fromData(outByteArray, "jpg"));
addPicture(picList);
//requestImage(picList.id, QSize(20, 20), QSize(20, 20));
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
}
//---Function is called in xmui.cpp---//
void PictureModel::setContext(QQmlContext* root){
//---Sets rootContext for model to be used in userListModel QML---//
root->setContextProperty("PictureModel", this);
}
int PictureModel::rowCount(const QModelIndex &parent) const{
Q_UNUSED(parent);
return m_picList.count();
}
QHash<int, QByteArray> PictureModel::roleNames() const{
QHash<int, QByteArray> roleNames;
roleNames.insert(nameRole, "picName");
return roleNames;
}
QVariant PictureModel::data(const QModelIndex &index, int role) const{
if (index.row() < 0 || index.row() >= m_picList.count()){
return QVariant();
}
QVariant text;
if(role == nameRole){
PictureModelStruct pList = m_picList.at(index.row());
text = pList.picname;
}
return text;
}
void PictureModel::addPicture(const PictureModelStruct &picList){
beginInsertRows(QModelIndex(), 0, 0);
m_picList.insert(0, picList);
endInsertRows();
}
//---Selects name of pictures from DB for display---//
bool PictureModel::selectPictureName(){
dbConnect();
emit showBusy(true);
QSqlQuery selectQuery(m_selectPictureDB);
bool sqlBool;
sqlBool = selectQuery.prepare("SELECT DISTINCT picName FROM picTable ORDER BY picName ASC");
if(sqlBool){
if(selectQuery.exec()){
qDebug()<<"PictureModel::selectPictureName() select picName sql statement executed fine";
}
}
else{
emit xmui->alertMsg(QMessageBox::Warning, "Database selectPicture Error Message 1", "Error: sql select script..."+selectQuery.lastError().text());
qDebug()<<"PictureModel::selectPictureName() Error with sql statement execution " << selectQuery.lastError();
return selectQuery.exec();
}
PictureModelStruct picList;
beginResetModel();
m_picList.clear();
while (selectQuery.next()){
picList.picname = selectQuery.value(1).toString();
addPicture(picList);
}
endResetModel();
emit showBusy(false);
m_selectPictureDB.close();
return selectQuery.exec();
}
To copy to clipboard, switch view to plain text mode
Bookmarks