在QML

时间:2017-08-19 16:19:13

标签: c++ qt sqlite qml blob

我2天前遇到这个问题,很难解决这个问题。我花了很多时间去搜索/研究,但我没有收到任何结果。

请帮帮我。

这是我的问题:

我有一个表数据库,它有一个列BLOB类型,我查询它,获取数据图像并在listview qml中显示它。但它失败了!!!

这是我的代码

MDisplayImage.h

#ifndef MDISPLAYIMAGE_H
#define MDISPLAYIMAGE_H
#include <QQuickPaintedItem>
#include <QImage>
#include <QtQuick/qquickitem.h>
class MDisplayImage:public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
public:
    explicit MDisplayImage(QQuickItem * parent): QQuickPaintedItem(parent){}
    QImage image() const { return *m_image;}
    void setImage(const QImage& image);
    void paint(QPainter *painter) Q_DECL_OVERRIDE;
    MDisplayImage();
private:
    QImage* m_image;
signals:
   void imageChanged();
};

#endif // MDISPLAYIMAGE_H

MDisplayImage.cpp

#include "MDisplayImage.h"
#include <QPainter>

MDisplayImage::MDisplayImage()
{

}
void MDisplayImage::setImage(const QImage &image){
    m_image = image;
    emit imageChanged();
    update();
    setImplicitHeight(image.height());
    setImplicitWidth(image.width());
}
void MDisplayImage::paint(QPainter *painter){
    m_image = m_image.scaled(width(), height(),Qt::KeepAspectRatio);
    if(m_image.isNull()) return;
    painter->drawImage(0,0,m_image);

}

的main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MDataBaseTableModel.h"
#include "MDisplayImage.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    MDataBaseTableModel *objectModel = new MDataBaseTableModel(0);

    QQmlApplicationEngine engine;
    qmlRegisterType<MDisplayImage>("ImageConnected",1,0,"MDisplayImage");
    engine.rootContext()->setContextProperty("modelSQL",objectModel);
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

和main.qml文件

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import ImageConnected 1.0
ApplicationWindow {
    visible: true
    width: 1350
    height: 760
    title: qsTr("Hello World")

    header: ToolBar{
        Label{
            text: qsTr("Welcome")
            font.pixelSize: 50
            anchors.centerIn: parent
        }
    }

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Page1 {
            StackView{
                id: stackView
                anchors.fill: parent
                initialItem: MainPage{}
            }
        }



        Page {
            Label {
                text: qsTr("Second page")
                anchors.centerIn: parent
            }
        }
    }

    footer: TabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex
        TabButton {
            text: qsTr("First")
        }
        TabButton {
            text: qsTr("Second")
        }
    }

}

//}

MainPage.qml文件

import QtQuick 2.4
import QtQuick.Controls 2.0
Page {
    //property Image test
    GridView {
        id: gridViewPro
        x: 50
        y: 100
        width: 1350
        height: 760
        model : modelSQL
        delegate: ItemDelegate{
            width: 450
            height: 320

            SubProduct{}
            MouseArea{
                anchors.fill: parent
                onClicked: stackView.push("qrc:/Detail.qml", {man : Vendor})
            }


        }
        highlight: Rectangle {
            width: 500
            height :400
            color: "red"; radius: 5
        }
        focus: true
        cellWidth: 500
        cellHeight: 400
    }

}

和SubProduct.qml文件

import QtQuick 2.0
import QtQuick.Layouts 1.3
import ImageConnected 1.0
ColumnLayout{
    spacing: 0
    Rectangle{
        Layout.alignment: Qt.AlignCenter
        Layout.preferredWidth: 450
        Layout.preferredHeight: 300
        RowLayout{
            spacing: 0
            Rectangle{
                Text{
                    text : Original //Original display fine in UI, it is column name of my database, this text show fine
                }
                id: imagePlace
                Layout.minimumWidth: 150
                Layout.minimumHeight: 300
                MDisplayImage{
                    id: newImage
                    width: 150
                    height:300
                    anchors.fill: parent
                    image: imageData //imagedata is a column of my database has type BLOB and it not display
                }

//                color: "#e0e1c5"
//                Text{
//                    text: number
//                }

            }
            Rectangle{
                id:infor
                Layout.minimumWidth: 300
                Layout.minimumHeight: 300
                ColumnLayout{
                    spacing: 0
                    Rectangle{
                        Layout.minimumWidth: 300
                        Layout.minimumHeight: 270
                        color: "#df745a"
                    }
                    Rectangle{
                        Layout.minimumWidth: 150
                        Layout.minimumHeight: 30
                        color: "yellow"
                        Button{
                            width: 300
                            height: 30
                        }

                    }
                }
            }

        }

    }
    Rectangle{
        Layout.alignment: Qt.AlignCenter
        Layout.preferredWidth: 450
        Layout.preferredHeight: 20
        color: "#8dd321"
//        Text{
//            text:name
//        }
    }
}

MDatabaseTableModel.h

#ifndef MDATABASETABLEMODEL_H
#define MDATABASETABLEMODEL_H
#include <QSqlTableModel>
#include <QSqlDatabase>

class MDataBaseTableModel:public QSqlTableModel
{
    Q_OBJECT
public:
    MDataBaseTableModel();
    explicit MDataBaseTableModel(QObject * parent =0);
    void connectDb();
    QVariant data(const QModelIndex &idx, int role) const Q_DECL_OVERRIDE;
    QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
private:
    QSqlDatabase m_db;
};

#endif // MDATABASETABLEMODEL_H

MDatabaseTableModel.cpp

#include "MDataBaseTableModel.h"
#include <QDebug>
#include <QSqlError>
#include <QSqlTableModel>

#include <QDebug>
#include <QByteArray>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QModelIndex>
#include <QSqlError>
MDataBaseTableModel::MDataBaseTableModel()
{

}
MDataBaseTableModel::MDataBaseTableModel(QObject *parent):
    QSqlTableModel(parent)
{
    connectDb();
    QString nameTable = "productMarket";
    setTable(nameTable);
    QSqlQuery queryObject;
    queryObject.prepare("SELECT * FROM productMarket");
    queryObject.exec();
    this->setQuery(queryObject);
}
QVariant MDataBaseTableModel::data(const QModelIndex &idx, int role) const
{
    if (role < Qt::UserRole)
        return QSqlTableModel::data(idx, role);

    const QSqlRecord sqlRecord = record(idx.row());
    return sqlRecord.value(role - Qt::UserRole);
}
QHash<int, QByteArray> MDataBaseTableModel::roleNames() const
{
    QHash<int, QByteArray> colums;
    colums[Qt::UserRole] = "productID";
    colums[Qt::UserRole+1] = "Name";
    colums[Qt::UserRole+2] = "Type";
    colums[Qt::UserRole+3] = "Vendor";
    colums[Qt::UserRole+4] = "Original";
    colums[Qt::UserRole+5] = "Price";
    colums[Qt::UserRole+6] = "State";
    colums[Qt::UserRole+7] = "imageData";
    colums[Qt::UserRole +8] = "Promotion";
    return colums;
}
void MDataBaseTableModel::connectDb(){
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName("/home/actiso/Test_DB/example.db");

    if(m_db.open()){
        qDebug()<< "query to database successfully";
    }else{
        qDebug()<< "query to database failed"<< m_db.lastError();
    }
}

运行程序时,数据库文本显示正常,但图像无法显示。 setImage()函数未被调用,但仍调用paint()函数

请帮帮我!!!

1 个答案:

答案 0 :(得分:2)

根据http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html

中的建议

问题是自定义QQuickPaintedItem正在等待QImage类型数据的类,因此您必须在模型中返回此类型之一:

<强> sqltablemodel.h

#ifndef SQLTABLEMODEL_H
#define SQLTABLEMODEL_H

#include <QSqlTableModel>

class SqlTableModel : public QSqlTableModel
{
public:

    SqlTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase());
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;

    QHash<int, QByteArray> roleNames() const;
};

#endif // SQLTABLEMODEL_H

<强> sqltablemodel.cpp

#include "sqltablemodel.h"
#include <QSqlRecord>
#include <QImage>

SqlTableModel::SqlTableModel(QObject *parent, QSqlDatabase db):
    QSqlTableModel(parent, db)
{
}

QVariant SqlTableModel::data(const QModelIndex &index, int role) const
{
    QVariant value;

    if (index.isValid()) {
        if (role < Qt::UserRole) {
            value = QSqlTableModel::data(index, role);
        } else {
            int columnIdx = role - Qt::UserRole - 1;
            QModelIndex modelIndex = this->index(index.row(), columnIdx);
            value = QSqlTableModel::data(modelIndex, Qt::DisplayRole);
            //imagedata is the name of blob type column
            if(roleNames().value(role) == "imagedata")
                return QImage::fromData(value.toByteArray());
        }
    }
    return value;
}


QHash<int, QByteArray> SqlTableModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    for (int i = 0; i < record().count(); i ++) {
        roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
    }
    return roles;
}

注意:此实现的优点是角色是使用表中每个字段的名称自动创建的

输出:

enter image description here