Reputation: 332
It is made clear in the docs that the C++ class that has the list must inherit from QObject but it's not clear if the objects inside the list must be QObjects.
I have tried this approach with a QQmlListProperty and also with a QQmlListProperty, but I get the following errors in both cases:
QMetaProperty::read: Unable to handle unregistered datatype 'QQmlListProperty<QString>
' for property 'ns::Status::values'
Edit: My code:
.hpp:
namespace ns{
class Status : public QObject
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QString> values READ values NOTIFY valuesChanged)
public:
Status(QObject* parent = Q_NULLPTR);
virtual ~Status();
bool updateValues(const std::vector<std::string>& values);
QQmlListProperty<QString> values();
int valueCount() const;
QString* value(int) const;
signals:
void valuesChanged();
private:
QVector<QString*> m_values_;
std::vector<QString> m_valueStorage_;
static int valueCount(QQmlListProperty<QString>*);
static QString* value(QQmlListProperty<QString>*, int);
};
}
.cpp:
using namespace ns;
Status::Status(QObject* parent) :
QObject(parent),
m_values_(2),
m_valueStorage_(2)
{}
Status::~Status(){}
bool Status::updateValues(const std::vector<std::string>& values)
{
//Do Stuff
emit valuesChanged();
return true;
}
QQmlListProperty<QString> Status::values()
{
return QQmlListProperty<QString>(this, nullptr, &Status::valueCount, &Status::value);
}
int Status::valueCount() const
{
return m_values_.count();
}
QString* Status::value(int index) const
{
return m_values_.at(index);
}
int Status::valueCount(QQmlListProperty<QString>* list){
return reinterpret_cast<Status*>(list->data)->valueCount();
}
QString* Status::value(QQmlListProperty<QString>* list, int i){
return reinterpret_cast<Status*>(list->data)->value(i);
}
QML:
import Foo 1.0
Rectangle {
Status {
id: status
objectName: "Status"
}
Component {
id: value
Rectangle { Text: {text: modelData } }
}
ColumnLayout {
Repeater { model: status.values; delegate: value }
}
}
Also, in my main, before I load the qml file into the QQmlApplicationEngine:
qmlRegisterType<ns::Status>("Foo", 1,0, "Status");
Upvotes: 3
Views: 1245
Reputation: 7170
QQmlListProperty
is indeed meant to be used with QObject
.
Although there's nothing in the class enforcing this limit since it's all templated, the QML engine expect the element type to be a subclass of QObject.
An indication in the Qt documentation that this is the case can be found in the doc of QQmlListReference
(a class made to manipulate QQmlListProperty
from c++).
This paragraph mentions QObject
:
QML list properties are type-safe. Only QObject's that derive from the correct base class can be assigned to the list. The listElementType() method can be used to query the QMetaObject of the QObject type supported. Attempting to add objects of the incorrect type to a list property will fail.
The QObject *QQmlListReference::at(int index) const
method is also another clue.
Upvotes: 6