You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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
    }
}

注意事项

  1. 确保Paintable类的paint方法正确重写父类虚函数,补充override关键字避免编译问题。
  2. 若需在QML中直接创建Paintable对象(而非通过C++列表传递),需在main.cpp中注册类型:
    qmlRegisterType<Paintable>("com.example", 1, 0, "Paintable");
    
    当前场景是直接传递C++实例,无需额外注册。
  3. 若Repeater的父容器为布局类(如Row、Column),Paintable对象会自动适配布局规则,无需手动设置位置。

内容的提问来源于stack exchange,提问作者arcrer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:54:24