mysql – Qt获取的数据库记录字段值为空,数据库中的数据为EXISTS

我有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>
点赞