Overview
This example demonstrates how to populate a QML ListView using a custom data model created in C++. The ListView displays items with custom text content and configurable background colors.
DataObject Implementation
The DataObject class serves as the data container for each list item. To expose a C++ class to the QML system, it must inherit from QObject and include the Q_OBJECT macro.
class DataObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(QString bgColor READ bgColor WRITE setBgColor NOTIFY bgColorChanged)
public:
DataObject(QObject *parent = nullptr);
DataObject(const QString &title, const QString &bgColor, QObject *parent = nullptr);
QString title() const;
void setTitle(const QString &title);
QString bgColor() const;
void setBgColor(const QString &bgColor);
signals:
void titleChanged();
void bgColorChanged();
private:
QString m_title;
QString m_bgColor;
};
The Q_PROPERTY macro registers each property with the QML meta-object system, enabling automatic property reading and writing through QML.
Registering Data in Main Function
Use QQmlContext::setContextProperty() to expose C++ objects to the QML context. This makes the data directly accessible from QML code.
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QList<QObject*> itemList;
itemList.append(new DataObject("Entry 1", "red"));
itemList.append(new DataObject("Entry 2", "green"));
itemList.append(new DataObject("Entry 3", "blue"));
itemList.append(new DataObject("Entry 4", "yellow"));
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
QQmlContext *context = view.rootContext();
context->setContextProperty("listModel", QVariant::fromValue(itemList));
view.setSource(QUrl("qrc:view.qml"));
view.show();
return app.exec();
}
Accessing Properties in QML Delegate
Once registered, the model data becomes available within the ListView delegate. Each property registered with Q_PROPERTY can be accessed directly by its name, which invokes the corresponding getter method.
ListView {
width: 100
height: 100
model: listModel
delegate: Rectangle {
height: 25
width: parent.width
color: model.modelData.bgColor
Text { text: title }
}
}
In the delegate, properties declared in DataObject are accessible through model.modelData. For properties with names that conflict with built-in QML properties (like color), use the fully qualified model.modelData.bgColor syntax to avoid ambiguity.
Notes
- Property names in QML resolve directly to getter methods defined in the C++ class
- When a property name shadows a QML property, use the
model.modelData.prefix to explicitly reference the data object - The
Q_PROPERTYNOTIFY signal ensures QML bindings update when C++ properties change