我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()
函数
请帮帮我!!!
答案 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;
}
注意:此实现的优点是角色是使用表中每个字段的名称自动创建的
输出: