如何在QML中显示C++ QQuickPaintedItem对象列表?
问题描述
我有一组继承自QQuickPaintedItem的C++对象,每个对象都能自行绘制内容。请问如何在QML中显示这组对象?我想使用Repeater组件,但如果将Repeater的model设置为该列表,由于这些对象可以自行绘制,我应该指定什么作为delegate?
相关代码
RandomObject.h
class RandomObject { Q_OBJECT Q_PROPERTY(QList<Paintable*> paintable_list READ paintableList NOTIFY paintableListChanged) public: RandomObject(QObject* parent=nullptr); QList<Paintable*> paintableList(); signals: void paintableListChanged(); };
Paintable.h
class Paintable : public QQuickPaintedItem { Q_OBJECT public: Paintable(QQuickPaintedItem* parent=nullptr); protected: void paint(QPainter* painter) override; // 补充override关键字确保正确重写 };
main.cpp
int main(int argc, char *argv[]) { if (qEnvironmentVariableIsEmpty("QTGLESSTREAM_DISPLAY")) { qputenv("QT_QPA_EGLFS_PHYSICAL_WIDTH", QByteArray("213")); qputenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT", QByteArray("120")); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); } QGuiApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps); RandomObject random; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("RandomObject", &random); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
main.qml(待完善)
Window { width: 640 height: 600 visible: true title: qsTr("Hello World") Repeater { model: RandomObject.paintable_list delegate: // 需要填写的内容 } }
解决方案
你的Paintable类继承自QQuickPaintedItem,本身就是QML可直接识别渲染的Item类型,因此在Repeater的delegate中直接引用modelData即可——modelData对应列表中的每一个Paintable实例。
基础用法
直接将modelData作为delegate,让每个Paintable对象成为Repeater的子项:
Repeater { model: RandomObject.paintable_list delegate: modelData }
自定义布局与属性
如果需要给每个Paintable对象设置位置、大小等属性,可直接在modelData上扩展:
Repeater { model: RandomObject.paintable_list delegate: modelData { width: 100 height: 100 x: index * 110 // 利用index属性实现横向排列 y: 50 } }
注意事项
- 确保
Paintable类的paint方法正确重写父类虚函数,补充override关键字避免编译问题。 - 若需在QML中直接创建
Paintable对象(而非通过C++列表传递),需在main.cpp中注册类型:
当前场景是直接传递C++实例,无需额外注册。qmlRegisterType<Paintable>("com.example", 1, 0, "Paintable"); - 若Repeater的父容器为布局类(如
Row、Column),Paintable对象会自动适配布局规则,无需手动设置位置。
内容的提问来源于stack exchange,提问作者arcrer
相关产品推荐
相关产品推荐

