从MySQL数据库

时间:2015-08-11 09:00:28

标签: c++ mysql qt qml

我是我的测试数据库,我有一个名为 users 的表,它代表了可记录的用户。现在,我通过Qt / C ++成功连接到数据库,将类暴露给QML(也没有问题),设置QML ListView以向用户显示自定义模型和委托(文件main.qml)当我运行我的应用程序时,ListView中显示了五个项目。现在,ListView's委托由图片文字部分(图片部分)组成,用于可记录的用户图片,其位置为 mysql数据库中的BLOB 和用户名的文本部分,在mysql数据库中也作为 VARCHAR 存在 - 这两个字段都位于名为 users <的同一个表中/强>):

import QtQuick 2.3

Item
{
    id: uePeopleItemDelegate

    property Image uePersonImage
    property string uePersonName

    width: 256
    height: 256
    antialiasing: true

    clip: true

    Rectangle
    {
        id: ueRectangleMain
        color: "#000000"

        radius: 16
        anchors.fill: parent
        antialiasing: true
        border.color: "#ffffff"
        border.width: 4
        clip: true
        //opacity: 0.7

        Grid
        {
            antialiasing: true
            anchors.rightMargin: 12
            anchors.leftMargin: 12
            anchors.bottomMargin: 12
            anchors.topMargin: 12
            anchors.fill: parent
            spacing: 4
            rows: 2
            columns: 1
        }

        Row
        {
            id: ueRowImage
            anchors.rightMargin: 12
            anchors.leftMargin: 12
            anchors.bottom: parent.bottom
            anchors.right: parent.right
            anchors.left: parent.left
            anchors.top: parent.top
            anchors.bottomMargin: 48
            anchors.topMargin: 12
        }

        Image
        {
            id: uePersonleImage
            x: 12
            y: 12
            width: 232
            height: 196
            antialiasing: true
            fillMode: Image.PreserveAspectFit
            source: ""
        }

        Column
        {
            id: ueColumnPeopleInfo
            x: 12
            y: 214
            width: 232
            height: 30
            spacing: 0
        }

        Text
        {
            id: ueTextPersonName
            x: 12
            y: 214
            width: 232
            height: 30
            color: "#ffffff"
            text: uePersonName
            font.bold: true
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            font.pixelSize: 16
        }
    }
}

以下是代表的截图: ListView delegates

如果我在数据库中删除/添加用户,则委托数量会根据表用户记录的数量而变化,这非常有效。但现在我有两个问题:在main.qml中,我实例化ListView

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtMultimedia 5.0
import QtQuick.Layouts 1.0
import QtTest 1.1

import "gui/delegates"

ApplicationWindow
{
    id: ueWindowMain

    title: qsTr("TestApp")

    width: Screen.desktopAvailableWidth
    height: Screen.desktopAvailableWidth

    visible: true

    opacity: 1.0

    contentOrientation: Qt.LandscapeOrientation

    color: "black"

    ListView
    {
        id: uePeopleListView
        snapMode: ListView.SnapToItem
        highlightRangeMode: ListView.ApplyRange
        anchors.right: parent.right
        anchors.rightMargin: 0
        anchors.bottom: parent.top
        anchors.bottomMargin: -128
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.top: parent.top
        anchors.topMargin: 0
        orientation: ListView.Horizontal
        flickableDirection: Flickable.HorizontalFlick
        antialiasing: true
        spacing: 16
        delegate: UePeopleItemDelegate
        {
            id: uePersonDelegate

            uePersonImage: ""   // Q1: How do I retreive image (user image) from database?
            uePersonName: ""    // Q2: How do I retreive text (user name) from database?
        }
        model: uePeopleModel
    }
}

如何检索数据(图像和文字)以在 49 50 行中的代表中显示?这里还有我的模型类的标题和实现:

#ifndef UEPEOPLEMODEL_H
#define UEPEOPLEMODEL_H

#include <QImage>
#include <QVariant>
#include <QStringList>
#include <QDebug>
#include <QHash>
#include <QByteArray>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQueryModel>
#include <QtSql/QSqlRecord>
#include <QModelIndex>

#include "../settings/uedefaults.h"

class UePeopleModel : public QSqlQueryModel
{
    Q_OBJECT

private:
    QHash<int, QByteArray> m_ueRoleNames;

    void ueGenerateRoleNames();

public:
    UePeopleModel(QObject *parent=0);
    ~UePeopleModel();

    QVariant data(const QModelIndex &index,
                  int role) const Q_DECL_OVERRIDE;
    void ueRefresh();
    inline QHash<int, QByteArray> ueRoleNames() const
        { return this->m_ueRoleNames; }
};

#endif // UEPEOPLEMODEL_H

和实施:

#include "uepeoplemodel.h"

UePeopleModel::UePeopleModel(QObject* parent)
    : QSqlQueryModel(parent)
{
    QSqlDatabase db;

    if(!QSqlDatabase::connectionNames().contains(UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE,
                                                 Qt::CaseInsensitive))
    {
            db=QSqlDatabase::addDatabase(UePosDatabase::DATABASE_DRIVER,
                                         UePosDatabase::UeDatabaseConnectionNames::DATABASE_CONNECTION_NAME_PEOPLE);
    }   // if

    db.setHostName(/*this->uePosSettings()->ueDbHostname()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    db.setDatabaseName(/*this->uePosSettings()->ueDbName()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    db.setUserName(/*this->uePosSettings()->ueDbUser()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    db.setPassword(/*this->uePosSettings()->ueDbPassword()*/UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);

    if(db.open())
    {
        this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
                       db);
        this->ueGenerateRoleNames();
    }
    else
    {
        qDebug() << db.lastError().text();
    }
}   // default constructor

UePeopleModel::~UePeopleModel()
{
}   // default destructor

QVariant UePeopleModel::data(const QModelIndex &index,
                             int role) const
{
    QVariant value;

    if(role<Qt::UserRole)
    {
        value=QSqlQueryModel::data(index,
                                   role);
    }
    else
    {
        int iColumnIndex=role-Qt::UserRole-1;
        QModelIndex modelIndex=this->index(index.row(),
                                           iColumnIndex);

        value=QSqlQueryModel::data(modelIndex,
                                   Qt::DisplayRole);
    }   // if

    return value;

//    QVariant value=QSqlQueryModel::data(index,
//                                        role);

//    if(value.isValid()&&role==Qt::DisplayRole)
//    {
//        switch(index.column())
//        {
//            case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_ID:
//                return value.toInt();

//            case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME:
//                return value.toString();

//            case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD:
//                return value.toString();

//            case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_CARD:
//                return value.toString();

//            case UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE:
//            {
//                QImage image;

//                image.loadFromData(value.toByteArray());

//                return image;
//            }   // case

//            default:
//                return value;
//        }   // switch
//    }   // if

//    return QVariant();
}   // data

void UePeopleModel::ueRefresh()
{
    this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE);
}   // ueRefresh

void UePeopleModel::ueGenerateRoleNames()
{
    this->ueRoleNames().clear();
    for(int iIndex=0; iIndex<this->record().count(); iIndex++)
    {
        this->ueRoleNames().insert(Qt::UserRole+1+iIndex,
                                   this->record().fieldName(iIndex).toUtf8());
    }   // for
}   // ueGenerateRoleNames

1 个答案:

答案 0 :(得分:1)

默认的QML图像提供程序只能使用URL或文件路径。如果要从C ++图像类加载QML图像,例如http://androidgifts.com/navigation-view-using-design-support-library/#comment-11 QPixmap,则必须执行并实现自己的图像提供程序。我已经描述了one possible implementation strategy here

之后它非常简单,QImage方法不会返回包含在data()中的图片,只是一个针对自定义图片提供商的自定义图片网址,而且#&# 39; s你将在QML代表中使用什么。当然,在数据库内部,您仍然会有一个blob,并且仍然会使用QVariant方法构建图像,但是图像提供程序将用于将自定义图像源字符串与实际图像相关联。当然,您必须找到一种方法来控制实际图像的生命周期,这样您就不会发生内存泄漏。我的建议是从上面列出的答案中实现类似fromData()项目的内容,并将其作为代理的一部分 - 这样,不再需要时将删除图像。但是,您还需要为Pixmap实施setData()并以文本形式传递Pixmap指针,并将其存储在QPixmap中。

将图像存储在数据库中可能更容易,更明智,但作为常规文件,只需在数据库中存储相对路径,就可以省去一些麻烦。至于问题&#34;如何检索数据&#34; - 我说去那里,实际上read the documentation ......