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

时间:2015-08-24 08:56:07

标签: mysql qt

我有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文档中它说:

  

如果未初始化模型,将返回空记录。

指向文档的链接: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

在行int nrrecords=this->rowCount(QModelIndex());之后我设置了一个断点,临时变量nrrecord保持值5 - 这是数据库中记录的数量!那么为什么方法的参数index为空?通过QML项data()属性从QML文件调用model方法。

1 个答案:

答案 0 :(得分:2)

至少存在以下问题:

  1. 您的转换案例全部落空(每个案件后必须break)。

  2. 您不需要私人会员的任何访问者,您应该直接使用它们。这就是为什么他们是私人的。当您希望 public (或 protected )接口隔离实现详细信息时,将使用访问器作为封装。删除m_ueDb的访问者并直接使用该成员。

  3. data的实施只会为图像角色提供值。您必须将默认角色访问权转发给基类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);
    }
    
  4. 您绝不能使用<QtModule/QtHeader>包含样式。您所做的表明您的.pro文件未声明使用sql模块和/或您尚未重新运行 qmake 将模块添加到项目后的项目(QT += sql文件中的某处应该有.pro。修复如下:

    // CORRECT
    #include <QSqlError>
    // WRONG
    #include <QtSql/QSqlError>