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

标签 mysql qt

我有连接到数据库的 Qt/QML 应用程序,现在我想通过子类 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

现在,问题是我从数据库中获取空值,因此 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

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

最佳答案

至少存在以下问题:

  1. 你的 switch cases 都失败了(你必须在每个 switch cases 之后 break)。

  2. 您不需要私有(private)成员的任何访问器,您应该直接使用它们。这就是为什么他们是私有(private)的。当您希望将实现细节与公共(public)(或 protected )接口(interface)隔离时,访问器用作封装。删除 m_ueDb 的访问器并直接使用成员(member)。

  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>
    

关于mysql - Qt取数据库记录字段值为空,数据库中数据EXISTS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32178173/

相关文章:

java - 用 Java 填充 HashMap

php - 如何从一个表中选择id并插入到另一个表中

php - cakephp - 从两个不相关的表中获取结果

java - JavaFX TableView 中的 MySQL 日期格式

qt - 带有 GLFW 和 Qt 的 OpenGL 游戏引擎?

mysql - Mysql 数据透视表

qt - qDebug() 的奇怪行为导致应用程序崩溃

c++ - 缩放 QTableWidget

c++ - 来自 QFrame 的 Qt 气球窗口

qt - 在槽函数运行时显示一个 "Please wait..."框