QML Combobox 报告 ReferenceError: modelData is not defined

Posted

技术标签:

【中文标题】QML Combobox 报告 ReferenceError: modelData is not defined【英文标题】:QML Combobox reports ReferenceError: modelData is not defined 【发布时间】:2015-09-30 09:24:23 【问题描述】:

我有以下简单的 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 运行时错误:

file:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562: ReferenceError:未定义模型数据 file:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562: ReferenceError:未定义模型数据 file:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562: ReferenceError:未定义模型数据 file:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562: ReferenceError:未定义模型数据 file:///opt/QtOpenSource55/5.5/gcc_64/qml/QtQuick/Controls/ComboBox.qml:562: ReferenceError: modelData 未定义

整个应用程序在ma​​in.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

为什么会出现这个错误?

【问题讨论】:

警告或错误?看到组件中的数据了吗? @BaCaRoZzo 我认为这些是运行时警告,我看到了组件,但其中没有数据,但是表示警告/错误的运行时字符串包含单词ReferenceError,因此我得出结论这是错误的,而不是警告。 嗯,了解uePeopleModel 会有所帮助。这条路真的很难。 @BaCaRoZzo 显示uePeopleModel,但它在ListView 中完美运行,我认为uePeopleModel 没有问题! 【参考方案1】:

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

【讨论】:

我知道帮助提问者可能为时已晚,但是当我遇到这个问题时,谷歌将我发送到这里,因此希望值得回答。 这对我有用。值得注意的是,用于 QML textRole 属性的值应该与 roleNames() 的 QAbstractListModel 实现中返回的期望值相匹配

以上是关于QML Combobox 报告 ReferenceError: modelData is not defined的主要内容,如果未能解决你的问题,请参考以下文章

解决QML开发中ComboBox中一个已选择项没有清除的问题

QML 可以多选ComboBox的实现

QML中的ComboBox SQL QT 5.10.1

QML ComboBox风格

如何正确地将 ComboBox 的模型从 python (pyQt5) 传递给 QML?

在 QML 中填充 Combobox 模型时如何使用 csv 列表?