我有Qt / QML应用程序连接到数据库,现在我想通过sublcassed QSqlQueryModel获取数据:
#ifndef UEPEOPLEMODEL_H
#define UEPEOPLEMODEL_H
#include <QImage>
#include <QVariant>
#include <QStringList>
#include <QDebug>
#include <QHash>
#include <QByteArray>
#include <QSqlError>
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QModelIndex>
#include <QQuickImageProvider>
#include <QByteArray>
#include <QSqlRecord>
#include <QDebug>
#include <QSqlQuery>
#include "../settings/uedefaults.h"
#include "../settings/uetypes.h"
class UePeopleModel : public QSqlQueryModel,
public QQuickImageProvider
{
Q_OBJECT
private:
QSqlDatabase m_ueDb;
private:
QSqlDatabase ueDatabase() const
{ return this->m_ueDb; }
void ueSetDatabase(const QSqlDatabase& database)
{ this->m_ueDb=database; }
public:
UePeopleModel(QObject *parent=0);
~UePeopleModel();
QVariant data(const QModelIndex &index,
int role) const Q_DECL_OVERRIDE;
QImage ueImage(const QString &id) const;
QImage requestImage(const QString &id,
QSize *size,
const QSize &requestedSize);
UeTypeRoles roleNames() const;
public:
static const int ueRoleName=Qt::UserRole+1;
static const int ueRoleImage=Qt::UserRole+2;
};
#endif // UEPEOPLEMODEL_H
这是实施:
#include "uepeoplemodel.h"
UePeopleModel::UePeopleModel(QObject* parent)
: QSqlQueryModel(parent),
QQuickImageProvider(QQmlImageProviderBase::Image,
QQmlImageProviderBase::ForceAsynchronousImageLoading)
{
//QSqlDatabase db;
if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
Qt::CaseInsensitive))
{
this->ueSetDatabase(QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE));
} // if
this->ueDatabase().setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
this->ueDatabase().setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
this->ueDatabase().setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
this->ueDatabase().setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);
if(this->ueDatabase().open())
{
this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
this->ueDatabase());
//qDebug() << this->ueDatabase().lastError().text();
}
else
{
qDebug() << this->ueDatabase().lastError().text();
}
} // default constructor
UePeopleModel::~UePeopleModel()
{
} // default destructor
QVariant UePeopleModel::data(const QModelIndex &index,
int role) const
{
QVariant value=QVariant();
switch(role)
{
case ueRoleImage:
{
value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
break;
} // case
case ueRoleName:
{
value=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
break;
} // case
default:
return value;
} // switch
return QSqlQueryModel::data(index,
role);//value;
} // data
QImage UePeopleModel::ueImage(const QString &id) const
{
return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
"PNG");
} // image
QImage UePeopleModel::requestImage(const QString &id,
QSize *size,
const QSize &requestedSize)
{
Q_UNUSED(requestedSize);
QImage image=this->ueImage(id);
*size = image.size();
return image;
} // requestImage
UeTypeRoles UePeopleModel::roleNames() const
{
UeTypeRoles roles;
const int iRoleName=UePeopleModel::ueRoleName;
const int iRoleImage=UePeopleModel::ueRoleImage;
roles.insert(iRoleName,
"ueRoleName");
roles.insert(iRoleImage,
"ueRoleImage");
return roles;
} // roleNames
现在,问题是我从数据库中获取了emtpty值,因此qml输出错误:
> qrc:/gui/windows/UeKeypad.qml:140:43: Unable to assign [undefined] to
> QString qrc:/gui/windows/UeKeypad.qml:140:43: Unable to assign
> [undefined] to QString qrc:/gui/windows/UeKeypad.qml:118:33: QML
> Image: Failed to get image from provider:
> image://uepeoplemodel/undefined qrc:/gui/windows/UeKeypad.qml:118:33:
> QML Image: Failed to get image from provider:
> image://uepeoplemodel/undefined qrc:/gui/windows/UeKeypad.qml:140:43:
> Unable to assign [undefined] to QString
> qrc:/gui/windows/UeKeypad.qml:140:43: Unable to assign [undefined] to
> QString qrc:/gui/windows/UeKeypad.qml:140:43: Unable to assign
> [undefined] to QString qrc:/gui/windows/UeKeypad.qml:140:43: Unable to
> assign [undefined] to QString qrc:/gui/windows/UeKeypad.qml:118:33:
> QML Image: Failed to get image from provider:
> image://uepeoplemodel/undefined qrc:/gui/windows/UeKeypad.qml:118:33:
> QML Image: Failed to get image from provider:
> image://uepeoplemodel/undefined qrc:/gui/windows/UeKeypad.qml:118:33:
> QML Image: Failed to get image from provider:
> image://uepeoplemodel/undefined qrc:/gui/windows/UeKeypad.qml:118:33:
> QML Image: Failed to get image from provider:
> image://uepeoplemodel/undefined
为什么我从表中获取空值?!
嗯,我一直在研究问题,在Qt文档中它指出:
If the model is not initialized, an empty record will be returned.
文档的链接:QSqlQueryModel::record.这可能是问题,但是,我在main.cpp中初始化UePeopleModel:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
UePeopleModel* uePeopleModel=new UePeopleModel(qApp);
engine.rootContext()->setContextProperty("uePeopleModel",
uePeopleModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
我还缺少什么?我已经多次检查数据库连接,没关系,我也从表中获取字段名称,但没有数据.
嗯,我已经将调试代码添加到QVariant UePeopleModel :: data(const QModelIndex& index,int role)const方法:
QVariant UePeopleModel::data(const QModelIndex &index,
int role) const
{
switch(role)
{
case ueRoleImage:
{
return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
break;
} // case
case ueRoleName:
{
int nrrecords=this->rowCount(QModelIndex());
QString name=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();;
return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
} break; // case
case ueRolePassword:
{
QString password=this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
} break; // case
default:
return QVariant();
} // switch
return QSqlQueryModel::data(index,
role);//value;
} // data
并且在行之后nrrecords = this-> rowCount(QModelIndex());我设置了一个断点,临时变量nrrecord保持值5 – 这是数据库中记录的数量!那么为什么方法的参数索引为空? data()方法是通过QML项目模型属性从QML文件调用的.
最佳答案 至少存在以下问题:
>您的开关箱全部掉落(每个开关箱必须断开).
>您不需要私有成员的任何访问者,您应该直接使用它们.这就是为什么他们是私人的.当您想要将实现细节与公共(或受保护)接口隔离时,访问器将用作封装.删除m_ueDb的访问器并直接使用该成员.
>您的数据实现仅提供图像角色的值.您必须将默认角色访问转发到基类的data():
QVariant UePeopleModel::data(const QModelIndex &index, int role) const
{
switch(role) {
case ueRoleImage:
for(int iIndex=0; iIndex<this->record().count(); iIndex++) {
qDebug() << this->record().fieldName(iIndex) <<
<< this->record().value(iIndex) <<
<< index.row();
}
return record(index.row()).value(
UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray();
case ueRoleName:
return record(index.row()).value(
UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
}
return QSqlQueryModel::data(index, role);
}
>你永远不应该使用< QtModule / QtHeader>包括风格.这样做表明你的.pro文件没有声明使用sql模块和/或你没有在项目中添加模块后重新运行qmake(你应该在某个地方使用QT = sql)你的个人资料).修复如下:
// CORRECT
#include <QSqlError>
// WRONG
#include <QtSql/QSqlError>