QML Combobox报告ReferenceError:未定义modelData

时间:2015-09-30 09:24:23

标签: combobox model qml

我有以下简单的QML组合框:

import QtQuick 2.0
import QtQuick.Controls 1.4

import si.mikroelektronika 1.0

Item
{
    id: ueStaffSelector

    width: 256
    height: 96

    ComboBox
    {
        model: uePeopleModel

        editable: false

        anchors.fill: parent
    }   // ComboBox
}   // Item

正如您所看到的,我将uePeopleModel分配给它,这在应用程序中已经正常工作。应用程序执行后,我会收到以下QML运行时错误:

  

文件:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562:   ReferenceError:未定义modelData   文件:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562:   ReferenceError:未定义modelData   文件:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562:   ReferenceError:未定义modelData   文件:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562:   ReferenceError:未定义modelData   文件:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562:   ReferenceError:未定义modelData

整个应用程序构建在 main.cpp

#include <QtQml>
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QTimer>

#include "database/uepeoplemodel.h"
#include "core/ueapplicationstatus.h"
#include "core/uedatabaseconnectionstatus.h"
#include "core/uebluetoothmanager.h"
#include "core/uebluetoothprinterconnectionstatus.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    UeApplicationStatus* ueApplicationStatus=new UeApplicationStatus(qApp);
    UePeopleModel* uePeopleModel=new UePeopleModel(qApp);
    UeBluetoothManager* ueBtManager=new UeBluetoothManager(qApp);

    QObject::connect(uePeopleModel,
                     SIGNAL(ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSlotDatabaseConnectionChanged(UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus)));

    QObject::connect(ueBtManager,
                     SIGNAL(ueSignalBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)),
                     ueApplicationStatus,
                     SLOT(ueSlotBtPrinterConnectionChanged(UeBluetoothPrinterConnectionStatus::UeTypeBluetootPrinterConnectionStatus)));

    engine.rootContext()->setContextProperty("uePeopleModel",
                                             uePeopleModel);
    engine.rootContext()->setContextProperty("ueApplicationStatus",
                                             ueApplicationStatus);
    engine.rootContext()->setContextProperty("ueBtManager",
                                             ueBtManager);

    engine.addImageProvider(QLatin1String("uePeopleModel"),
                            uePeopleModel);

    qmlRegisterUncreatableType<UeDatabaseConnectionStatus>("si.mikroelektronika",
                                                           1,
                                                           0,
                                                           "UeTypeDatabaseConnectionStatus",
                                                           "Database Connection Status");

    qmlRegisterUncreatableType<UeBluetoothPrinterConnectionStatus>("si.mikroelektronika",
                                                                   1,
                                                                   0,
                                                                   "UeTypeBluetootPrinterConnectionStatus",
                                                                   "Bluetooth Printer Connection Status");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    uePeopleModel->ueConnectToDatabase();
    ueBtManager->ueStartPairing();

    //ueApplicationStatus->ueUpdate(uePeopleModel->ueFetchUsers());

    return app.exec();
}

这里还有UePeopleModel标题,文件 UePeopleModel.h

#ifndef UEPEOPLEMODEL_H
#define UEPEOPLEMODEL_H

#include <QImage>
#include <QVariant>
#include <QStringList>
#include <QHash>
#include <QByteArray>
#include <QSqlError>
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QModelIndex>
#include <QQuickImageProvider>
#include <QByteArray>
#include <QSqlRecord>
#include <QSqlQuery>

#include "../settings/uedefaults.h"
#include "../core/uedatabaseconnectionstatus.h"
#include "../core/uetypes.h"
#include "../core/ueapplicationstatus.h"
#include "../core/ueuserrecord.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; }
    QImage ueImage(const QString& id) const;

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

    QVariant data(const QModelIndex &index,
                  int role) const Q_DECL_OVERRIDE;
    QImage requestImage(const QString &id,
                        QSize *size,
                        const QSize &requestedSize);
    UeTypeRoles roleNames() const;
    void ueConnectToDatabase();
    UeTypeUsers* ueFetchUsers();

public:
    static const int ueRoleName=Qt::UserRole+1;
    static const int ueRoleImage=Qt::UserRole+2;
    static const int ueRolePassword=Qt::UserRole+3;

signals:
    void ueSignalDatabaseConnectionChanged(const UeDatabaseConnectionStatus::UeTypeDatabaseConnectionStatus& newStatus);
};

#endif // UEPEOPLEMODEL_H

及其实现,文件 UePeopleModel.cpp

#include "uepeoplemodel.h"

UePeopleModel::UePeopleModel(QObject* parent)
    : QSqlQueryModel(parent),
      QQuickImageProvider(QQmlImageProviderBase::Image,
                          QQmlImageProviderBase::ForceAsynchronousImageLoading)
{
    emit this->ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::NOT_CONNECTED);
}   // default constructor

UePeopleModel::~UePeopleModel()
{
    QString connName=this->ueDatabase().connectionName();

    this->ueDatabase().close();
    this->ueSetDatabase(QSqlDatabase());
    this->ueDatabase().removeDatabase(connName);

    emit this->ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::NOT_CONNECTED);
}   // default destructor

QVariant UePeopleModel::data(const QModelIndex &index,
                             int role) const
{
    switch(role)
    {
        case ueRoleImage:
        {
            return QString::number(index.row());
        } break;    // case

        case ueRoleName:
        {
            return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString();
        } break;    // case

        case ueRolePassword:
        {
            return this->record(index.row()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString();
        } break;   // case

        default:
        {
            return QSqlQueryModel::data(index,
                                        role);
        } break;    // default
    }   // switch

    return QVariant();
}   // data

QImage UePeopleModel::ueImage(const QString &id) const
{
    return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
                            "PNG").scaled(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
                                          UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
                                          Qt::IgnoreAspectRatio,
                                          Qt::SmoothTransformation);
}   // ueImage

QImage UePeopleModel::requestImage(const QString &id,
                                   QSize *size,
                                   const QSize &requestedSize)
{
    Q_UNUSED(size)
    Q_UNUSED(requestedSize);

//    if(size)
//    {
//        *size=QSize(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
//                    UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT);
//    }   // if

    //return this->ueImage(id);

    return QImage::fromData(this->record(id.toInt()).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_IMAGE).toByteArray(),
                            "PNG").scaled(UeDefaults::UeGraphics::PEOPLE_IMAGE_WIDTH,
                                          UeDefaults::UeGraphics::PEOPLE_IMAGE_HEIGHT,
                                          Qt::IgnoreAspectRatio,
                                          Qt::SmoothTransformation);
}   // requestImage

UeTypeRoles UePeopleModel::roleNames() const
{
    UeTypeRoles roles;

    const int iRoleName=UePeopleModel::ueRoleName;
    const int iRoleImage=UePeopleModel::ueRoleImage;
    const int iRolePassword=UePeopleModel::ueRolePassword;

    roles.insert(iRoleName,
                 "ueRoleName");
    roles.insert(iRoleImage,
                 "ueRoleImage");
    roles.insert(iRolePassword,
                 "ueRolePassword");

    return roles;
}   // roleNames

void UePeopleModel::ueConnectToDatabase()
{
    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(UePosDatabase::UeDatabaseConnectionParameters::DATABASE_HOSTNAME);
    this->ueDatabase().setDatabaseName(UePosDatabase::UeDatabaseConnectionParameters::DATABASE_NAME);
    this->ueDatabase().setUserName(UePosDatabase::UeDatabaseConnectionParameters::DATABASE_USERNAME);
    this->ueDatabase().setPassword(UePosDatabase::UeDatabaseConnectionParameters::DATABASE_PASSWORD);

    if(this->ueDatabase().open())
    {
        this->setQuery(UePosDatabase::UeSqlQueries::UeTablePeople::SQL_QUERY_GET_ALL_PEOPLE,
                       this->ueDatabase());
        emit this->ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::CONNECTED);
    }
    else
    {
        emit this->ueSignalDatabaseConnectionChanged(UeDatabaseConnectionStatus::NOT_CONNECTED);
    }   // if
}   // ueConnectToDatabase

UeTypeUsers* UePeopleModel::ueFetchUsers()
{
    UeTypeUsers* users=new UeTypeUsers();

    for(int iIndex=0; iIndex<this->record().count(); iIndex++)
    {
        users->append(new UeUserRecord(this,
                                       this->record(iIndex).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_ID).toString(),
                                       this->record(iIndex).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_NAME).toString(),
                                       this->record(iIndex).value(UePosDatabase::UeTableIndexes::UeTablePeople::INDEX_APPPASSWORD).toString()));
    }   // for

    return users;
}   // ueFetchUsers

为什么我收到此错误?

1 个答案:

答案 0 :(得分:10)

您需要告诉组合框使用哪个角色。尝试将textRole: "ueRoleName"添加到ComboBox