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 未定义
整个应用程序在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
为什么会出现这个错误?
【问题讨论】:
警告或错误?看到组件中的数据了吗? @BaCaRoZzo 我认为这些是运行时警告,我看到了组件,但其中没有数据,但是表示警告/错误的运行时字符串包含单词ReferenceError
,因此我得出结论这是错误的,而不是警告。
嗯,了解uePeopleModel
会有所帮助。这条路真的很难。
@BaCaRoZzo 显示uePeopleModel
,但它在ListView
中完美运行,我认为uePeopleModel
没有问题!
【参考方案1】:
您需要告诉组合框使用哪个角色。尝试将textRole: "ueRoleName"
添加到您的ComboBox
。
【讨论】:
我知道帮助提问者可能为时已晚,但是当我遇到这个问题时,谷歌将我发送到这里,因此希望值得回答。 这对我有用。值得注意的是,用于 QML textRole 属性的值应该与 roleNames() 的 QAbstractListModel 实现中返回的期望值相匹配以上是关于QML Combobox 报告 ReferenceError: modelData is not defined的主要内容,如果未能解决你的问题,请参考以下文章
解决QML开发中ComboBox中一个已选择项没有清除的问题